In the Serverless world, Azure Functions are a complete solution to create a small piece of code that runs without worrying about preparing a whole infrastructure to host it. In this article, we will talk about Microsoft Azure Functions and Microsoft Azure Durable Functions – that is an extension to it.
What are Microsoft Azure Functions?
The term serverless computing indicates an evolution of a paradigm named Platform as a Service (PasS). Generally, cloud providers run and manage servers which are dynamically allocated resources to executed code. Often, serverless computing is also referred to as Functions as a Service (FasS).
Azure Functions is the service in Microsoft Azure that allows users to create an event-driven FasS. As developers, we can create an Azure Function using a programming language of our choice from many available.
Also, Azure Functions have a straightforward pricing model:
- Consumption plan: we only pay for the time that code runs;
- App Service plan: we only pay for the App Service’s monthly fee;
- Premium plan: right now in preview, promising maximum performances.
Depending on what pricing model we choose, we can quickly scale our functions using an event-driven or manual mechanism.
Let’s see the first example of Azure Function. First of all, we need to have an active Microsoft Azure subscription. We can register for a free account here. Then, we can log into our account and select “Create a resource” button. Next, let’s follow these steps: type “Functions” inside the search box, select “Functions App” and press the create button.
For the Function App, we need to specify the following fields:
- an app name;
- a resource group;
- an OS;
- a hosting plan type;
- allocation type;
- a runtime stack;
- Storage.
Once created, we can go to the resource, and we can see a window that shows us different types of triggers for our function, like in the following image:
In this page, we can add a new function choosing what development environment we want to use and what type of trigger we need. A trigger is a mechanism that starts our function execution. There are many triggers available such as HTTP, Timer, Azure Queue Storage, Azure Service Bus, Azure Event Hub, Azure Blob Storage, and so on.
Let’s choose a simple one for this example, an HTTP Trigger. First, we type a name and select the authentication type (i.e.: “Function”). Then Microsoft Azure will generate for us the function code and open the editor window:
From this point onwards, we can edit the function code as we need to and, in the end, we can run it pressing the button Run. Once running, we can use the test console on the left side to try calls and see the expected output.
This brief overview of Azure Functions gives an indication of how powerful they are: they offer a practical way to create lots of functions that will work on boring tasks that would need a lot of time just to prepare the infrastructure. The next section looks at how to use Microsoft Azure Functions such as orchestration to accomplish advanced tasks.
What are Microsoft Azure Durable Functions?
In some cases, where there’s a workflow involved that requires some stored state, we need to involve more complex scenarios . Unfortunately, Azure Functions are stateless, so Microsoft Azure Durable Functions came into play to cover such situations: in fact, this is an extension that allows you to write stateful functions that manage state, checkpoints, and restarts.
Since Durable functions offer a way to orchestrate other functions, they can help to create workflows in which status is saved automatically using storage. Oh, and they have a history too!
These kinds of functions can be used for the following patterns:
- Chaining: to chain a sequence of functions in a specific order;
- Fan-Out/Fan-In: to execute multiple long-running tasks without a particular order and without waiting for them to complete;
- Async HTTP APIs: usually implemented for long-running jobs;
- Monitoring: to monitor processes or operations;
- Human interaction: to create a process that needs human intervention to be completed.
From the point of view of pricing, the durable functions extension follows the same pricing model as Azure functions (more info here).
Let’s look at an example of Azure Durable function using the Fan-Out/Fan-In pattern. We will use Visual Studio Code and its extension for Azure Functions (you can download this from GitHub). Once installed, pressing F1 inside VS code will open the command palette where we can search for “functions” and select “Azure functions: create new project”, then choose a directory and a programming language. In this situation, we select:
- “DurableFunctionsOrchestration” as a template
- a name and a namespace for our function;
- an Azure Web Jobs Storage to help run our function.
We also need to install Azure Functions Core Tools as explained here.
Once the project functionhas been created, we have a first Durable Function that has three methods:
- RunOrchestrator
- SayHello
- HttpStart
Each method has an Attribute in its parameters signature:
- OrchestrationTrigger (1) does the orchestration between different functions. It launches and retrieves data;
- ActivityTrigger (2) represents the functions called by the orchestrator and handles that work.
- OrchestrationClient (3) starts or ends the functions and let us query their status.
Let’s replace the code in our RunOrchestrator method to implement the Fan-Out pattern with the snippet below:
[FunctionName("CodemotionDurableFunction")]
public static async Task<List<string>> RunOrchestrator(
[OrchestrationTrigger] DurableOrchestrationContext context)
{
var inputs = new List<string>() { "Tokyo", "Seattle", "London" };
// Fan-out
var tasks = new Task<string>[inputs.Count];
for(int i = 0; i < inputs.Count; i++)
{
tasks[i] = context.CallActivityAsync<string>(
"CodemotionDurableFunction_Hello", inputs[i]);
}
await Task.WhenAll(tasks);
return tasks.Select(t => t.Result).ToList();
}
Before running, let’s have a look at the code. The method HttpStart will start our orchestrator using the name in the FunctionName attribute (the previous snippet is named CodemotionDurableFunction).
The method SayHello prints out a welcome string based on the input parameter. Finally, RunOrchestrator is where the Fan-Out happens. First, we create a loop based on the input parameters, and inside the loop, consecutively call in the function SayHello with a specific input.
After the loop, an await Task.WhenAll(tasks) awaits the completion of all tasks.
In the latest statement, we retrieve the outputs from each task.
To run the function in VS Code, we could press F5 on the keyboard to start the debugger. Once started, the console shows us an endpoint at which to start our orchestration:
Copy and paste the URL into the browser. The call responds with a payload with many fields: we need to use statusQueryGetUri to check the status and get the results. The output from this call looks like this:
["Hello Tokyo!","Hello Seattle!","Hello London!"]
Conclusion
As we have seen, Azure Durable Functions is a potent tool that offers us the opportunity to create complex workflows for any task. This article only offers a short introduction, so if this sounds appealing we advise checking out the complete documentation here.