Azure 持久功能 - 在 Orchestrator 中执行

问题描述

我有一个协调器,它调用一个活动函数来处理客户 ID 此活动的输出返回错误 ID(如果有),我希望通过再次执行活动来重新处理这些 ID,直到没有错误 ID(输出为空)。

为编排器设置 do 循环是一种好习惯吗? 如何在每次执行 Activity 之前包含 5 分钟延迟?

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";
    }

解决方法

也许您可以使用持久计时器来延迟执行,请先参考Timers in Durable Functions (Azure Functions)

Durable Functions 提供了持久的计时器,用于在协调器函数中实现延迟或设置异步操作的超时。应在协调器函数中使用持久计时器,而不是 Thread.Sleep 和 Task.Delay (C#),或 setTimeout() 和 setInterval() (JavaScript),或 time.sleep() (Python)。

这是延迟使用的代码示例:

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";
    }