我读到有关 Eternal Orchestration here 的文章,我们可以通过调用 ContinueAsNew 来让 Orchestrator “无限地”运行,这将重置其状态。
编排器是否立即重新运行?或者只有在执行完函数中的所有语句后(即基于下面的代码,当if条件被满足或它是否跳出函数时,“函数结束”才会被注销并重新执行协调器?)?
[FunctionName("Periodic_Cleanup_Loop")]
public static async Task Run(
[OrchestrationTrigger] IDurableOrchestrationContext context, ILogger log)
{
await context.CallActivityAsync("DoCleanup", null);
// sleep for one hour between cleanups
DateTime nextCleanup = context.CurrentUtcDateTime.AddHours(1);
await context.CreateTimer(nextCleanup, CancellationToken.None);
if (condition)
context.ContinueAsNew(null);
log.logInformation("End of the function");
}
谢谢!
答案 0 :(得分:0)
执行将始终完成,直到函数结束或遇到某些错误为止。这意味着您会看到“函数结束”被记录。如果您有许多 ContinueAsNew,则只有最后一次执行才会在函数终止时运行。在实践中,你可以在使用 ContinueAsNew 后做任何事情
例如
[FunctionName("Orch")]
public static async Task Orchestrator(
[OrchestrationTrigger] IDurableOrchestrationContext context, ILogger log)
{
int input = context.GetInput<int>();
await context.CallActivityAsync<string>("Acti", input.ToString());
context.ContinueAsNew(input + 1);
context.ContinueAsNew(input + 2);
await context.CallActivityAsync<string>("Acti", input.ToString() + " : second");
log.LogInformation("End of the function");
}
[FunctionName("Acti")]
public static async Task Activity(
[ActivityTrigger] IDurableActivityContext inputs, ILogger log)
{
log.LogInformation(inputs.GetInput<string>());
}
这会记录。
0
0 : second
End of the function
2
2 : second
End of the function
4
4 : second
End of the function
...
context.ContinueAsNew 真正做的只是告诉编排上下文在函数终止时启动一个具有相同 InstanceId 的新编排器。在代码中的某处使用 ContinueAsNew 与将 context.StartAsNew("Orch", /*random instanceId*/, input)
放在函数的绝对末尾“几乎”相同。唯一的区别是,当函数终止时,StartAsNew 将开始在 TableStorage 中创建新的执行历史记录,而 ContinueAsNew 将重用相同的历史记录,这可能会减少一些故障排除选项,但会节省存储空间。