【问题标题】:Why the "runtimeStatus" in "statusQueryGetUri" not set immediately after timer is finished?为什么“statusQueryGetUri”中的“runtimeStatus”没有在计时器完成后立即设置?
【发布时间】:2021-01-13 17:23:20
【问题描述】:

为什么“runtimeStatus”仅在 52 秒后设置为“已完成”而不是我在 context.CreateTimer() 函数中设置的 30,当使用 statusQueryGetUri http 请求检查它时?强>

The documentation that I used

我的代码

 [FunctionName("H")]
            public static async Task<HttpResponseMessage> Start([HttpTrigger(AuthorizationLevel.Anonymous, "get","post",Route = "route/{route}")] HttpRequestMessage req, [DurableClient] IDurableOrchestrationClient client, string route) 
            {
                    string id = await client.StartNewAsync("Or1");
                    return client.CreateCheckStatusResponse(req, id);
               
            }
            [FunctionName("Or1")]
            public static async Task<string> Or1([OrchestrationTrigger] IDurableOrchestrationContext context, ILogger logger) 
            {
        
                using (CancellationTokenSource cts = new CancellationTokenSource()) 
                {
        
                    DateTime endTime = context.CurrentUtcDateTime.AddSeconds(30);
                    logger.LogInformation($"*********time now {context.CurrentUtcDateTime}");
                    logger.LogInformation($"*********end Time {endTime}");
        
                    await context.CreateTimer(endTime, cts.Token);
                    logger.LogInformation($"*********end Time finish {context.CurrentUtcDateTime}");
        
                    return "timer finished";
        
                }
            }
            [FunctionName("Activity1")]
            public static async Task A1([ActivityTrigger] IDurableActivityContext context) 
            {
                //Do something
            }

日志

Functions:

        H: [GET,POST] http://localhost:7071/api/route/{route}

        Activity1: activityTrigger

        Or1: orchestrationTrigger

For detailed output, run func with --verbose flag.
[2021-01-13T16:17:06.841Z] Host lock lease acquired by instance ID '000000000000000000000000EB8F9C93'.
[2021-01-13T16:17:24.767Z] Executing 'H' (Reason='This function was programmatically called via the host APIs.', Id=0aeee0e1-6148-4c21-9aa9-d17a43bce8d1)
[2021-01-13T16:17:24.925Z] Executed 'H' (Succeeded, Id=0aeee0e1-6148-4c21-9aa9-d17a43bce8d1, Duration=164ms)
[2021-01-13T16:17:24.995Z] Executing 'Or1' (Reason='(null)', Id=6aa97b04-d526-41b1-9532-afb21c088b18)
[2021-01-13T16:17:25.006Z] *********time now 1/13/2021 4:17:24 PM
[2021-01-13T16:17:25.007Z] *********endTime 1/13/2021 4:17:54 PM
[2021-01-13T16:17:25.017Z] Executed 'Or1' (Succeeded, Id=6aa97b04-d526-41b1-9532-afb21c088b18, Duration=23ms)
[2021-01-13T16:18:16.476Z] Executing 'Or1' (Reason='(null)', Id=9749d719-5789-419a-908f-6523cf497cca)
[2021-01-13T16:18:16.477Z] *********time now 1/13/2021 4:17:24 PM
[2021-01-13T16:18:16.478Z] *********endTime 1/13/2021 4:17:54 PM
[2021-01-13T16:18:16.481Z] *********endTime finish 1/13/2021 4:18:16 PM
[2021-01-13T16:18:16.485Z] Executed 'Or1' (Succeeded, Id=9749d719-5789-419a-908f-6523cf497cca, Duration=9ms)

【问题讨论】:

    标签: c# azure-functions azure-durable-functions


    【解决方案1】:

    azure Orchestrater 处理 队列轮询,它作为随机指数退避算法实现,以减少空闲队列轮询对存储事务成本的影响。当找到一条消息时,运行时立即检查另一条消息;当没有找到消息时,它会等待一段时间,然后再重试。在后续尝试获取队列消息失败后,等待时间继续增加,直到达到最大等待时间,默认为 30 秒。

    如果查看您的日志,您会注意到 Orchestrater 在16:17:24 触发了计时器,并且在16:17:54 完成时,一条消息已添加到存储队列中。如上所述,由于队列轮询,似乎在16:18:16 处选择了消息以恢复编排执行。

    我相信,如果您多次触发持久功能,那么您会注意到每个实例完成编排的总时间会有所不同。

    您可以在here 阅读有关 Azure 函数编排队列轮询的信息。

    您还可以查看历史记录表以了解邮件何时排队以及何时被选中。在here阅读它。

    要显示排队的工作原理,您可以在触发计时器后立即停止该功能。以下是我的本地环境模拟器队列中的输出,显示在触发计时器时有消息排队

    现在当 Orchestrator 功能再次恢复时,它会从队列中轮询消息并选择它以进一步处理。

    注意 - 在我的本地环境中,我用你的代码尝试了几次,因为我注意到所有实例都在大约 30 秒内完成。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-04-09
      • 2016-09-27
      • 2023-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多