Retries with Azure Durable Functions
    • Dark
      Light
    • PDF

    Retries with Azure Durable Functions

    • Dark
      Light
    • PDF

    Article Summary

    #ServerlessTips - Azure Functions
    Author: Steef-Jan Wiggers Azure MVP

    With Durable functions, you have support for retries – when calling activity or other orchestration function (sub orchestration). You can customize within the CallActivityWithRetryAsync method, and the RetryOptions class the back-off strategy for retries.

    There are several options for customizing the automatic retry policy according to the Microsoft docs - they include the following:

    • Max number of attempts: The maximum number of retry attempts.
    • First retry interval: The amount of time to wait before the first retry attempt.
    • Backoff coefficient: The coefficient used to determine the rate of increase of backoff. Defaults to 1.
    • Max retry interval: The maximum amount of time to wait in between retry attempts.
    • Retry timeout: The maximum amount of time to spend doing retries. The default behaviour is to retry indefinitely.
    • Handle: A user-defined callback can be specified which determines whether or not a function call should be retried.

    In the following example we'll retry the MonitorActivity up to a maximum of ten attempts with a 30 seconds delay before retrying.

    var monitorActivity = await ctx.CallActivityWithRetryAsync<string>("MonitorActivity", 
                   new RetryOptions(TimeSpan.FromSeconds(30),10), inputData);
    

    The code above instructs the framework behind the Durable Functions to:

    • Retry up to ten times
    • Wait 30 seconds before retrying again

    When the MonitorActivity is called from the orchestrator and throws an exception - it will be the FunctionFailedException. However, you can examine the inner exception containing the actual exception from the activity and based on that exception you perform a retry.

    var a1 = await ctx.CallActivityWithRetryAsync<string>("MonitorActivity", 
        new RetryOptions(TimeSpan.FromSeconds(30),10)
        {
            Handle = ex => ex.InnerException.Message == "Monitoring failed."
        }, 
        inputData);
    

    When leveraging the RetryOptions class you set the options first:

    var options = new RetryOptions(
        firstRetryInterval: TimeSpan.FromMinutes(1),                    
        maxNumberOfAttempts: 10);
    options.BackoffCoefficient = 2.0;
    

    Next you set provide the options in the CallActivityWithRetrySync method:

    await context.CallActivityWithRetryAsync("MonitorActivity", options, itinerary);
    

    The above code instructs the framework behind the Durable Functions to:

    • Retry up to ten times
    • Wait for one minute before the first retry
    • Increase delays before every subsequent retry by the factor of 2 (1 min, 2 min, 4 min, etc.)
    The orchestrator does not block while awaiting retries - after a failed call, a message is scheduled for the moment in the future to re-run the orchestrator and retry the request.

    Was this article helpful?