Azure Durable Functions is a powerful tool for building scalable and reliable serverless applications on Azure. It allows you to write asynchronous code that can handle long-running tasks and workflows.
Durable Functions is built on top of Azure Storage and Azure Cosmos DB, providing a scalable and highly available infrastructure for your applications. This ensures that your functions can run without interruption, even in the event of failures or retries.
One of the key benefits of Durable Functions is its ability to handle retries and failures automatically, freeing you from the need to write complex error handling code. This makes it easier to build robust and fault-tolerant applications.
Durable Functions also provides a range of features for managing state and data, including support for Entity Framework and other popular data access libraries. This makes it easy to integrate Durable Functions with your existing data infrastructure.
Functionality
Azure Durable Functions offer a powerful way to simplify complex, stateful coordination requirements in serverless applications. With Durable Functions, you can create orchestrators that coordinate activity functions, which perform the "real work" in your workflow.
You can invoke activity functions by name, pass parameters, and return function output using the context.df object. This allows for seamless communication between functions and enables you to create more complex workflows.
Here are some key benefits of using Durable Functions:
- Function chaining
- Fan-out/fan-in
- Async HTTP APIs
- Monitoring
- Human interaction
- Aggregator (stateful entities)
The context object in JavaScript represents the entire function context, and you can access the Durable Functions context using the df property on the main context. This allows you to easily integrate Durable Functions with other Azure services.
The Technology
The Durable Functions extension is built on top of the Durable Task Framework, an open-source library on GitHub.
This framework is used to build workflows in code, making it a natural fit for the serverless Azure Functions environment.
Microsoft and other organizations use the Durable Task Framework extensively to automate mission-critical processes.
It's the serverless evolution of the Durable Task Framework, similar to how Azure Functions is the serverless evolution of Azure WebJobs.
Why?
Durable Functions allow for the creation of stateful workflows in a serverless environment, thanks to the Durable Task Framework that maintains checkpoints and handles restarts.
These workflows can be paused and resumed without worrying about any loss of state information, making it a game-changer for complex tasks.
In situations that would otherwise involve awkward chaining of functions or require external storage to maintain state, Durable Functions can simplify code and reduce complexity.
With Durable Functions, you can process messages in a specific order, aggregate data from multiple messages, or track progress across multiple messages, tasks that can be challenging with Service Bus alone.
This is particularly useful in scenarios where you need to manage and orchestrate tasks more efficiently.
Application
Function chaining is a common application pattern in Durable Functions, where a sequence of functions executes in a specific order. This is achieved by using queues between each function to ensure the system stays durable and scalable.
You can use Durable Functions to implement function chaining concisely, as shown in the example where the values F1, F2, F3, and F4 are the names of other functions in the same function app.
Activity functions are the basic unit of work in a durable function orchestration, and they can be executed serially, in parallel, or some combination of both. Unlike orchestrator functions, activity functions aren't restricted in the type of work you can do in them.
You can use an activity trigger to define an activity function, and it can only have a single value passed to it. To pass multiple values, you must use tuples, arrays, or complex types.
The primary use case for Durable Functions is simplifying complex, stateful coordination requirements in serverless applications. Typical application patterns that can benefit from Durable Functions include function chaining, fan-out/fan-in, async HTTP APIs, monitoring, human interaction, and aggregator (stateful entities).
You can use the context object to invoke other functions by name, pass parameters, and return function output. Each time the code calls yield, the Durable Functions framework checkpoints the progress of the current function instance.
Here are some common application patterns that can benefit from Durable Functions:
- Function chaining
- Fan-out/fan-in
- Async HTTP APIs
- Monitoring
- Human interaction
- Aggregator (stateful entities)
Entities and State
Entity functions define operations for reading and updating small pieces of state, known as durable entities.
Entity functions are functions with a special trigger type, entity trigger, and can be invoked from client functions or from orchestrator functions.
Entity functions manage state explicitly rather than implicitly representing state via control flow.
In Durable Functions 2.0 and above, entity functions are available for C#, JavaScript, and Python.
Entity functions and related functionality is only available in Durable Functions 2.0 and above.
Durable entities can be modeled as classes in .NET, which can be useful if the list of operations is fixed and becomes large.
Entity functions can be used to easily implement the aggregator pattern, which aggregates event data over a period of time into a single, addressable entity.
Orchestrator
An orchestrator function is a special type of function in Durable Functions that describes how actions are executed and the order in which they are executed. It's essentially a blueprint for your workflow.
Orchestrator functions can interact with entity functions, which manage state explicitly. They can also include various types of actions, such as activity functions, sub-orchestrations, and waiting for external events.
To create an orchestrator function, you can use the Azure Functions: Create Function feature in the command palette. You'll be prompted to select a template, and you should choose Durable Functions orchestrator. This will create a Durable Functions orchestration.
Here's a step-by-step guide to creating an orchestrator function:
- Select a template for your function: Choose Durable Functions orchestrator.
- Choose a durable storage type: Select Azure Storage (Default).
- Provide a function name: Enter a name for your function, such as HelloOrchestrator.
Each call to context.df.callActivity in an orchestrator function invokes an activity function. For example, in the HelloOrchestrator function, each call to context.df.callActivity invokes an activity function named Hello.
Aggregator (Stateful Entities)
Aggregator (Stateful Entities) is a pattern that helps you aggregate event data over time into a single entity. This pattern is useful when dealing with data from multiple sources, delivered in batches, or scattered over long periods.
Entity functions are the key to implementing this pattern. They define operations for reading and updating small pieces of state, making it easier to manage state explicitly rather than implicitly.
Durable entities can be used to easily implement this pattern as a single function. They can also be modeled as classes in .NET, which can be useful if the list of operations is fixed and becomes large.
Entity functions are available in Durable Functions 2.0 and above for C#, JavaScript, and Python. This means you can use them to create stateful entities that can be queried and signaled from clients.
Clients can enqueue operations for an entity function using the entity client binding. This allows them to interact with the entity in a type-safe way.
Client
Client functions are a crucial part of Azure Durable Functions, allowing you to trigger orchestrator functions and interact with running orchestrations and entities.
Any non-orchestrator function can be a client function, and it's defined by its use of the durable client output binding. This means you can trigger an orchestrator from an HTTP-triggered function, an Azure Event Hub triggered function, and so on.
You can use a client function to start an orchestrator, query its status, terminate it, or raise events to it. The durable client binding provides a lot of flexibility and power in managing your orchestrations and entities.
Here are some ways you can use client functions:
- Trigger an orchestrator from an HTTP-triggered function
- Query the status of an orchestrator
- Terminate an orchestrator
- Raise events to an orchestrator
Note that orchestrator and entity functions cannot be triggered directly using the Azure Portal buttons. Instead, you must run a client function that starts an orchestrator or entity function as part of its implementation.
Development and Deployment
To create a function app in Azure, you can use Visual Studio Code. Select F1 to open the command palette and enter "Azure Functions: Create Function App in Azure." This will prompt you to select your Azure subscription.
You'll need to provide a globally unique name for the function app, which is validated to ensure it's unique in Azure Functions. The name you choose is also used to name related resources created in your Azure subscription.
Selecting a runtime stack is also important, as you'll want to choose the language version you currently run locally. Additionally, you'll need to select a location for new resources, choosing an Azure region that's near you for better performance.
New Features in 2.x
Durable Functions 2.x introduced a new entity functions concept.
This new concept brings a lot of possibilities for developers, allowing them to create more complex and scalable workflows.
To take advantage of this feature, you'll need to install the latest 2.x version of the Durable Functions bindings extension in your project.
Python support in Durable Functions requires Durable Functions 2.x or greater, so make sure your project is up to date.
Upgrading to Durable Functions 2.x is relatively straightforward, and can be done by updating the extension bundle version in your project's host.json file.
To do this, simply update the extensionBundle section to use version 4.x, like this: [4.*, 5.0.0).
Upgrade the Extension
To upgrade the extension, you need to install the latest 2.x version of the Durable Functions bindings extension in your project. This is a crucial step in taking advantage of the new features in Durable Functions 2.x.
You can update the extension bundle version in your project by opening the host.json file and updating the extensionBundle section to use version 4.x ([4.*, 5.0.0)). This will ensure that you're using the latest version of the extension.
If you're using Visual Studio Code, you may need to reload the window after updating the extension bundle version. You can do this by running the Developer: Reload Window command (Ctrl+R on Windows and Linux, Command+R on macOS). This will refresh the IDE and ensure that you're seeing the correct templates.
Here are the steps to update the extension bundle version:
- Open the host.json file in your project.
- Update the extensionBundle section to use version 4.x ([4.*, 5.0.0)).
- Reload the Visual Studio Code window by running the Developer: Reload Window command.
By following these steps, you'll be able to upgrade the extension and start using the new features in Durable Functions 2.x.
Prerequisites and Setup
To get started with Azure Durable Functions, you'll need to have some essential tools and software installed. Visual Studio Code is a must-have, so make sure you have it installed on your computer.
You'll also need the Azure Functions extension installed in Visual Studio Code, and it should be version 1.10.4 or later. Additionally, Azure Functions Core Tools version 4.0.5382 or later is required.
An Azure subscription is necessary, and if you don't have one, you can create an Azure free account. You'll also need an HTTP test tool that keeps your data secure.
Here are the specific software requirements:
- Visual Studio Code installed.
- Azure Functions extension version 1.10.4 or later installed.
- Azure Functions Core Tools version 4.0.5382 or later installed.
- Azure subscription (create an Azure free account if needed).
- Node.js version 16.x+ installed.
- Node.js version 18.x+ installed.
- TypeScript version 4.x+ installed.
Frequently Asked Questions
When should I use durable Functions?
Use Azure Durable Functions for long-running processes and complex workflows that require coordination and error handling
What is the difference between durable function and service bus in Azure?
Durable Functions is ideal for complex workflows, while Azure Service Bus is best for high-volume messaging and decoupled services. Choose Durable Functions for streamlined workflow management or Azure Service Bus for reliable, scalable messaging needs
What is the difference between durable Functions and airflow?
Airflow and Durable Functions differ in their approach to triggering data processing pipelines, with Airflow using CRON models for backfilling and catchup executions, while Durable Functions relies on event-driven mechanisms. Choose between them based on your specific pipeline needs.
Sources
- https://learn.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-overview
- https://topuzas.medium.com/azure-durable-functions-an-end-to-end-guide-with-c-549bd4dfb720
- https://learn.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-types-features-overview
- https://learn.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-versions
- https://learn.microsoft.com/en-us/azure/azure-functions/durable/quickstart-ts-vscode
Featured Images: pexels.com