Azure耐用功能:我是否正确使用`!orchestrationContext.IsReplaying`?

时间:2019-12-20 09:26:51

标签: task azure-functions deterministic non-deterministic azure-durable-functions

我发现in Microsoft's example of fan-out无需担心针对重放的“防御”

但是我在这里肯定需要if (!orchestrationContext.IsReplaying)

[FunctionName(FUNC_NAME_ORCH)]
public static async Task<string> RunPlayerYouTubeOrchestration(
    [OrchestrationTrigger] DurableOrchestrationContext orchestrationContext,
    ILogger log)
{
    log?.LogInformation($"{FUNC_NAME_ORCH}: {nameof(RunPlayerYouTubeOrchestration)} invoked...");
    log?.LogInformation($"{FUNC_NAME_ORCH}: {nameof(DurableOrchestrationContextBase.InstanceId)} {orchestrationContex

    log?.LogInformation($"{FUNC_NAME_ORCH}: calling {FUNC_NAME_ORCH_FUNC0}.c ..");
    var jsonBlobs = await orchestrationContext
        .CallActivityAsync<IEnumerable<string>>(FUNC_NAME_ORCH_FUNC0, null);

    if ((jsonBlobs == null) || !jsonBlobs.Any())
    {
        var errorMessage = $"{FUNC_NAME_ORCH}: The expected JSON blobs from `{FUNC_NAME_ORCH_FUNC0}` are not here.";
        log?.LogError(errorMessage);
        throw new NullReferenceException(errorMessage);
    }

    if (!orchestrationContext.IsReplaying)
    {
        var tasks = jsonBlobs.Select(json =>
            {
                log?.LogInformation($"{FUNC_NAME_ORCH}: calling {FUNC_NAME_ORCH_FUNC1}...");
                return orchestrationContext.CallActivityAsync(FUNC_NAME_ORCH_FUNC1, json);
            });

        log?.LogInformation($"{FUNC_NAME_ORCH}: fan-out starting...");
        await Task.WhenAll(tasks);
    }

    log?.LogInformation($"{FUNC_NAME_ORCH}: fan-out complete.");

    log?.LogInformation($"{FUNC_NAME_ORCH}: calling {FUNC_NAME_ORCH_FUNC2}...");
    await orchestrationContext.CallActivityAsync(FUNC_NAME_ORCH_FUNC2, null);

    return orchestrationContext.InstanceId;
}

没有此if门,FUNC_NAME_ORCH_FUNC1将被无休止地调用

我在这里做错了什么?有没有使用!orchestrationContext.IsReplaying的“正确”时间,还是使用比确定性代码少的技巧?

1 个答案:

答案 0 :(得分:1)

我认为您的代码在没有IsReplaying的情况下应该可以正常工作。 CallActivityAsync()方法将被多次调用,但对于给定的输入,它将仅执行一次活动功能。第一次执行后,结果将被检查到表存储中,并且对该活动的后续调用将从表中返回结果,而不会再次执行活动功能。

有关检查点和重播的更多信息:https://docs.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-orchestrations#reliability

我建议您将FUNC1的日志记录语句移到FUNC1活动函数的内部。这样,您只需记录实际活动函数的执行情况,而不记录CallActivityAsync方法的调用时间。

相关问题