1
votes

I have an orchestrator that calls an activity function to process customer Id's The output of this activity returns error ID's (if there are any) and I wish to reprocess these Id's by executing the activity again until there are no error id's (output is null).

Is it good practice to have a do loop for an orchestrator? How do I include a 5 min delay before each time the activity gets executed?

public static async Task<string> RunOrchestrator(
        [OrchestrationTrigger] IDurableOrchestrationContext context, ILogger log)
    {
        log = context.CreateReplaySafeLogger(log);
        
        dynamic errorOutput = null;
        dynamic processCustomers = context.GetInput<dynamic>();
        log = context.CreateReplaySafeLogger(log);

        do
        {
            log.LogInformation("Calling activity");
            errorOutput = await context.CallActivityAsync<dynamic>("GetCSPCustomerLicenses_Activity", processCustomers);

            //Get customers to process from error object                   
            processCustomers = errorOutput;
            
           //Wait 5 minutes - how do I achieve this ?

        } while (errorOutput != null);

        return "Success";
    }
1
You can do Task.Wait, but a better pattern might be to fail the function and do the retry at the root caller, if it is a queue you can requeue. the reason is that if you have multiple functions calling each other and each of them makes a retry, then you will have exponential waits. - Carlos Garcia

1 Answers

0
votes

Maybe you can use durable timers for delaying execution, please refer to Timers in Durable Functions (Azure Functions) first:

Durable Functions provides durable timers for use in orchestrator functions to implement delays or to set up timeouts on async actions. Durable timers should be used in orchestrator functions instead of Thread.Sleep and Task.Delay (C#), or setTimeout() and setInterval() (JavaScript), or time.sleep() (Python).

This is a code sample for delay usage:

public static async Task<string> RunOrchestrator(
        [OrchestrationTrigger] IDurableOrchestrationContext context, ILogger log)
    {
        log = context.CreateReplaySafeLogger(log);
        
        dynamic errorOutput = null;
        dynamic processCustomers = context.GetInput<dynamic>();
        log = context.CreateReplaySafeLogger(log);

        do
        {
            log.LogInformation("Calling activity");
            errorOutput = await context.CallActivityAsync<dynamic>("GetCSPCustomerLicenses_Activity", processCustomers);

            //Get customers to process from error object                   
            processCustomers = errorOutput;
            
            //Wait 5 minutes - how do I achieve this ?
            DateTime deadline = context.CurrentUtcDateTime.Add(TimeSpan.FromMinutes(5));
            await context.CreateTimer(deadline, CancellationToken.None);
        } while (errorOutput != null);

        return "Success";
    }