Azure Functions
Last modified on Wed 23 Mar 2022

Azure Functions is a Function-as-a-Service (“FaaS”), i.e. a platform for running configurable blocks of code that run in response to some event. Functions support several different programming languages such as C# and JavaScript, F#, Java, Python, and PowerShell.

Main benefits of using Azure Functions and serverless solutions are:

There are three basic hosting plans available for Azure Functions:

Note: If there is already existing App service hosting some API that needs some background job to be executed, good candidate can be Azure Web job. To learn more, see here.

Scaling

A single function app in Consumption plan, scales out to the maximum of 200 instances, while a single instance can process more than one message / request at a time.

Timer trigger functions are singleton (trigger only one instance of function).

In real world scenarios we need to control scaling of instances. Sometimes azure functions deal with databases or other services which may have scaling limits so over-scaling azure functions could put other resources under pressure. Scaling rules can be configured for function depending on trigger type.

Example: If for some reason, we needed queue messages to be processed by a function one at a time, than we need to configure function app scale-out to one function instance. Than the function concurent proccessing should be limited too, and that is done by setting batchSize to 1 in the host.json. Learn more here and here.

Function properties

               {
           "retry":{
              "strategy":"fixedDelay",
              "maxRetryCount":2,
              "delayInterval":"00:00:03"
           }
        }

Note: Some of the triggers come with default retry logic. Queue triggered functions retry 5 times before sending message to poison queue, while the timer trigger function doesn't retry at all. When a time trigger function fails, it isn't called again until the next time on the schedule.

Function set up

Add as a new project, through VS Function App template. This creates azure function app that can contain multiple functions that share common configuration such as environment variables, app settings and host. All functions will be deployed together under same function-app umbrella and scaled together.

Triggers

To trigger function execution, different triggers can be used. Most popular ones are :

        [Function("FunctionName")]
        public void Run([TimerTrigger("0 */5 * * * *")] MyInfo myTimer)
        {
            _logger.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
            _logger.LogInformation($"Next timer schedule at: {myTimer.ScheduleStatus.Next}");
            // your logic
        }
        [FunctionName("QueueTrigger")]
        public static void Run(
            [QueueTrigger("myqueue-items", Connection = "StorageConnectionAppSetting")] string myQueueItem,
            ILogger log)
        {
           // your logic
        }

or with storage account settings configured as attribute


        [StorageAccount("ClassLevelStorageAppSetting")]
        public static class AzureFunctions
        {
            [FunctionName("QueueTrigger")]
            [StorageAccount("FunctionLevelStorageAppSetting")]
            public static void Run( //...
            {
            // your logic
            }
        }
        [Function("FunctionName")]
        public HttpResponseData Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req)
        {
            _logger.LogInformation("C# HTTP trigger function processed a request.");
            // your logic
            var response = req.CreateResponse(HttpStatusCode.OK);
            response.Headers.Add("Content-Type", "text/plain; charset=utf-8");
            response.WriteString("Welcome to Azure Functions!");
            return response;
        }

Function app files

Default function app consists of:

Host Configuration

Differences:

For more info read here.

.NET 6 functions support both in-process and out-of-process options, but out-of-process does not support all bindings and features supported in in-process. In .Net 7 out-of-process will support full set of features so out-of-process will be the only supported option. To find out more read here.

Best practices