Back
Blog
May 12, 2023
Introducing Durable Patterns for Azure Durable Functions
Lukasz C.
Azure Functions: a brief introduction
Azure Functions is a serverless approach provided by Microsoft. It is similar to AWS Lambda and Google Cloud Functions, providing a way to run code without worrying about resource management or provisioning. Users can run event-triggered code and pay only for what was used.
Durable Function Framework: a quick overview
Durable functions are extensions to Azure Functions that introduce state to serverless computing. They allow you to write stateful functions and workflows by introducing orchestrator and entity functions. There are several most common use cases of the framework that can be described by patterns:
Function chaining - where we run one activity function after another
Fan-out/fan-in - running multiple activity functions in parallel and waiting for the results
Human interaction
Async HTTP APIs
Monitoring
Aggregator (stateful entities)
How to make Durable Functions better?
Durable Function Framework is an extremely useful tool for running serverless workflows, but it can be improved. The need to create function classes, use many attributes, and generate a lot of boilerplate code means that the Durable Function SDK has significant room for improvement.
Durable Patterns to the rescue
Durable Patterns is a .NET library that simplifies usage of the Durable Function framework when leveraging main use patterns. It provides fluent interfaces to wrap business logic and, under the hood, it uses activity functions, async code and batching to make the best use of the durable framework. Developers can focus on writing business code without worrying about boilerplate. The fluent interface makes it easy to chain different pattern usages one after another in an intuitive way.
Let’s look at an example (the diagram at the top).
Function chaining with fan-out/fan-in
The following example shows an http trigger which starts the flow. It uses the GetItems
function to get a list of items, then the ProcessItem
function that works on every item. Each item is processed by one function for simplicity (Durable Patterns supports batching). After the parallel processing, the ProcessResults
function works on the result list.
Normally, we would need to create an orchestrator function like the one shown below:
Then, we need to write all the activity functions, either in separate classes (boilerplate) or in the same (messy), remembering all the attributes, etc.
We would also need to inject all the dependencies needed by any of the class to the Orchestrator class itself. It doesn’t look very dev friendly, right?
Luckily, we have a solution: Durable Patterns.
With Durable Patterns, we can easily define our Azure Functions using a fluent syntax that allows us to inject our dependencies without the need to modify the function signature.
Using Durable Patterns
Here is an example of how we can use Durable Patterns to simplify our code:
As we can see, we can now define our function in a single line using the RunActivity
and FanOutFanIn
methods. This syntax is much more concise and easier to read than the previous example.
Pattern activity classes
In the example above, we are using activity classes such as GetItemsActivity
or ProcessItemActivity
- these are defined by the user and encapsulate process logic. This is how GetItemsActivity
class could look like:
The logic in ProcessItemActivity
class will be executed in a fan-out-fan-in manner, which means the collection returned from the GetItemsActivity
step will be chunked into batches (in this example of size 1) and the ProcessItemActivity.RunAsync
will be executed in parallel (in a separate activity function) for each of these batches. An implementation of this class could look like this:
Configuring Fan Out Fan In
We can configure a FanOutFanIn steop easily by passing options to the method. Here is an example:
In this example, we are using the FanOutFanIn
method and passing options to it. We are specifying the maximum batch size, the maximum number of parallel functions.
What's Next?
Durable Patterns is an open-source project that you can find here. It's also available as a NuGet package.
Our team is planning to add support for the rest of the typical patterns, such as:
Async HTTP APIs
Monitoring
Aggregator (stateful entities).
We will also be adding support for other use cases that are not covered by the official patterns.
We welcome any contributors to join our project and help us improve it!