Building Powerful Cloud Solutions
Explore common orchestration and activity patterns for building robust, stateful serverless workflows.
Durable Functions provides a powerful way to orchestrate complex workflows composed of Azure Functions. By leveraging patterns, you can build resilient, scalable, and maintainable applications that handle long-running operations, state management, and human interaction seamlessly.
Execute a sequence of functions in a specific order, passing the output of one function as the input to the next. This is useful for linear workflows where tasks must be completed sequentially.
context.CallActivityAsync
.Example Orchestrator Snippet:
// C# Example
[FunctionName("FunctionChaining")]
public static async Task RunOrchestrator(
[OrchestrationTrigger] IDurableOrchestrationContext context)
{
var result1 = await context.CallActivityAsync("Activity1", "input1");
var result2 = await context.CallActivityAsync("Activity2", result1);
var finalResult = await context.CallActivityAsync("Activity3", result2);
return finalResult;
}
Execute multiple functions in parallel and then aggregate their results. This pattern is ideal for processing large amounts of data or tasks that can be performed independently.
Task.WhenAll
and then aggregates results.Example Orchestrator Snippet:
// C# Example
[FunctionName("FanOutFanIn")]
public static async Task RunOrchestrator(
[OrchestrationTrigger] IDurableOrchestrationContext context)
{
var inputs = new List<string> { "input1", "input2", "input3" };
var tasks = new List<Task<string>>();
foreach (var input in inputs)
{
tasks.Add(context.CallActivityAsync<string>>("ProcessData", input));
}
await Task.WhenAll(tasks);
var results = tasks.Select(t => t.Result).ToList();
// Aggregate results...
return $"Aggregated: {string.Join(", ", results)}";
}
Incorporate human approval or input into a workflow. Durable Functions can wait for external events, such as an email response or a manual approval in an application.
context.CreateTimer
and waits for an external event using context.WaitForExternalEventAsync
.Example Orchestrator Snippet:
// C# Example
[FunctionName("HumanInteraction")]
public static async Task RunOrchestrator(
[OrchestrationTrigger] IDurableOrchestrationContext context)
{
var requestId = context.GetInput<string>();
// Notify approver...
await context.CallActivityAsync("SendApprovalNotification", requestId);
// Wait for approval or rejection for a limited time
var timeout = TimeSpan.FromDays(3);
var expiration = context.CurrentUtcDateTime.Add(timeout);
await context.CreateTimer(expiration, CancellationToken.None);
var decision = await context.WaitForExternalEventAsync<string>("ApprovalDecision");
if (decision.ToLower() == "approved")
{
// Continue workflow...
await context.CallActivityAsync("ProcessApprovedRequest", requestId);
}
else
{
// Handle rejection...
await context.CallActivityAsync("NotifyRejection", requestId);
}
}
Handle long-running HTTP requests by delegating the work to Durable Functions and returning an immediate response with a status check URL.
202 Accepted
with a status query URL. The orchestrator performs the work.Note: This pattern often involves an HTTP-triggered function to start the orchestrator and another to poll for status.
Periodically check the status of an external system or a long-running process. This can involve using timers and calling activity functions to perform checks.
context.CreateTimer
to schedule recurring checks.Process a stream of events reliably, ensuring that each event is processed at least once, even in the face of failures.
The selection of a pattern depends on the specific requirements of your application. Consider:
Durable Functions also supports more advanced patterns like state-based workflows, complex event correlation, and bridging different types of integrations. Refer to the official Azure Functions Durable Functions documentation for in-depth details and advanced techniques.