Wednesday, 25 December 2024

Azure Durable Functions

What is a Durable Function?

A Durable Function is an extension of Azure Functions that allows you to write stateful workflows in a serverless environment. Durable Functions are part of the Durable Task Framework, which enables you to chain function calls, handle retries, and execute long-running processes without worrying about the limitations of the traditional stateless Azure Functions.

With Durable Functions, you can manage complex workflows that require coordination and long-running tasks like waiting for external events or managing retries.


Key Concepts of Durable Functions:

  1. Orchestrator Functions:

    • Purpose: Orchestrator functions define the workflow logic. They are responsible for calling other functions (called activity functions) in a defined order.
    • Behavior: Orchestrator functions are durable, meaning they can pause and resume without losing state. They are executed once and can call other functions in sequence, parallel, or even handle retries.
    • Example: You could have an orchestrator function that retrieves data from an Azure SQL Database, processes it, and then sends results to a downstream service.
  2. Activity Functions:

    • Purpose: Activity functions are the actual units of work within the durable workflow. They execute the tasks like querying a database, calling an API, processing data, etc.
    • Behavior: Activity functions are stateless and run as normal Azure Functions.
    • Example: An activity function could perform an SQL query, send an email, or process a file.
  3. Client Functions:

    • Purpose: These are regular Azure Functions that start the orchestration by calling the orchestrator function. They are typically HTTP-triggered and initiate the durable workflow.
    • Behavior: Client functions handle the initiation and monitor the progress or completion of the orchestration.
    • Example: An HTTP trigger might accept a request to start an orchestration that processes a file upload or runs a time-consuming SQL query.

Key Features of Durable Functions:

  1. Long-Running and State Preservation:

    • Durable Functions can run for extended periods (even days) and maintain state across retries and failures.
    • They can be paused and resumed by the Azure Durable Task framework, allowing them to handle long-running processes like waiting for external events or delays.
  2. Resiliency and Retry Mechanism:

    • Durable Functions can automatically retry operations in case of failure or timeouts, ensuring that long-running operations are resilient.
  3. Fan-Out and Fan-In Patterns:

    • Fan-Out: You can trigger multiple activities in parallel and wait for all of them to complete (useful for processing large datasets concurrently).
    • Fan-In: After the parallel operations, you can consolidate the results into a single output.
  4. Human Intervention:

    • They support waiting for external events or human intervention before proceeding with the next step. For example, you could wait for a user to approve or review something before continuing the workflow.

Example Workflow in Durable Functions:

Imagine a scenario where you need to query an Azure SQL Database and process the data over several steps, including retries for failures:

  1. Client Function (HTTP Trigger): Accepts a request to start the process (e.g., querying a database).
  2. Orchestrator Function:
    • Calls an Activity Function to query the database.
    • If the query takes a long time or is complex, it can be handled gracefully using Durable Functions.
    • Calls other activity functions to process the data (e.g., transformation, validation).
  3. Activity Function:
    • Executes the query and processes the data.
    • Handles retries if an error occurs (e.g., network failure, SQL timeout).
  4. Wait for External Event: If the process requires user confirmation or waiting for a response, the orchestrator can pause until the event is triggered.

Example Code Snippet for Durable Functions:

Here’s a simplified example of how you might set up a Durable Function workflow with a SQL query and processing.

  1. Orchestrator Function (DurableOrchestrator.cs):
[FunctionName("DurableOrchestrator")]
public static async Task RunOrchestrator(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    // Call the Activity Function to query the database
    var queryResult = await context.CallActivityAsync<string>("QueryDatabase", null);

    // Call another activity to process the data
    var processedData = await context.CallActivityAsync<string>("ProcessData", queryResult);

    return processedData;
}
  1. Activity Function to Query Database (QueryDatabase.cs):
[FunctionName("QueryDatabase")]
public static string QueryDatabase([ActivityTrigger] string name, ILogger log)
{
    // Execute SQL query and return result
    return "Query result from DB";
}
  1. Activity Function to Process Data (ProcessData.cs):
[FunctionName("ProcessData")]
public static string ProcessData([ActivityTrigger] string queryResult, ILogger log)
{
    // Process the data (e.g., transform, validate)
    return "Processed data: " + queryResult;
}
  1. Client Function (HTTP Trigger):
[FunctionName("StartWorkflow")]
public static async Task<HttpResponseMessage> StartWorkflow(
    [HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestMessage req,
    [DurableClient] IDurableOrchestrationClient starter,
    ILogger log)
{
    // Start the Durable Orchestration
    string instanceId = await starter.StartNewAsync("DurableOrchestrator", null);

    return starter.CreateCheckStatusResponse(req, instanceId);
}

Key Considerations:

  • Costs: While Durable Functions are great for long-running workflows, keep an eye on the execution time, as longer executions may increase costs, especially if using the Consumption plan.
  • State Management: Durable Functions maintain state, so you don’t need to manage it manually (e.g., in a database or external system).
  • Timeouts: Azure Durable Functions can run indefinitely, but they are subject to overall system limits, such as maximum execution duration.

Conclusion:

Durable Functions are ideal for complex, long-running workflows that require state management, resiliency, and asynchronous execution. They can handle tasks that take hours or days, while still being highly scalable and cost-efficient.

No comments:

Post a Comment