gpt4 book ai didi

Azure Durable编排功能ILogger输出两次日志

转载 作者:行者123 更新时间:2023-12-02 22:56:19 26 4
gpt4 key购买 nike

有几个相互调用的持久函数。主编排 -> 子编排 -> 事件 -> 辅助异步方法

每个函数都有 ILogger 依赖性,并在函数开始和函数结束时登录。由于某种原因,两个协调器都会重复“启动时”消息。 (见图)事件没有这种效果。 (见图)多次运行下面的示例 - 同一个故事。

我也确信整个过程已经被触发过一次。

这是协调器中的错误还是预期行为?

using System;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.DurableTask;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;

namespace Issues
{
public static class Log_Issue
{
[FunctionName("Main")]
public static async Task RunOrchestrator(
[OrchestrationTrigger] IDurableOrchestrationContext context,
ILogger log)
{
try
{
log.LogWarning("Main Start");
await context.CallSubOrchestratorAsync("Sub", null);
log.LogWarning("Main End");
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}

[FunctionName("Sub")]
public static async Task RunSubOrchestrator(
[OrchestrationTrigger] IDurableOrchestrationContext context,
ILogger log)
{
log.LogWarning("Sub Start");
var data = await context.CallActivityAsync<string>("Activity", null);
log.LogWarning("Sub End");
}

[FunctionName("Activity")]
public static async Task<string> GetDataActivity([ActivityTrigger] string name, ILogger log)
{
log.LogWarning("Activity Start");
var data = await GetDataAsync("https://www.google.com");
log.LogWarning("Activity End");

return data;
}

[FunctionName("Start")]
public static async Task<IActionResult> HttpStart(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")]
HttpRequestMessage req,
[DurableClient] IDurableOrchestrationClient starter,
ILogger log)
{
var instanceId = await starter.StartNewAsync("Main", null);
log.LogWarning($"Started orchestration with ID = '{instanceId}'.");
return new OkResult();
}

private static async Task<string> GetDataAsync(string url)
{
var httpClient = new HttpClient();

using var request = new HttpRequestMessage
{
RequestUri = new Uri(url),
Method = HttpMethod.Get,
};

var response = await httpClient.SendAsync(request);
response.EnsureSuccessStatusCode();

return await response.Content.ReadAsStringAsync();
}
}
}

Run Results

最佳答案

这是预期的。例如,在等待 context.CallActivityAsync("Activity", null); 上代码会自行暂停,甚至可能会加载到内存不足(为了节省成本)。

然后,协调器等待将事件放入该事件创建的另一个 Azure 存储表中,这可能会在许多天后发生。对于事件来说,它们通常是非常即时的,但它仍然等待该事件发生。

当发生这种情况时,代码需要从上次停止的地方开始,但没有办法做到这一点。因此,代码从头开始重新运行,但不是等待事件再次完成,而是首先查看表并发现我们已经完成了该事件并且可以继续运行。如果事件函数返回某个值,则该值将从await 调用中返回。在协调器的两次运行期间,它都会记录,但由于我们只进入仅记录的事件。

这就是为什么协调器必须是确定性的,因为例如第一次运行时的随机值与第二次运行期间的随机值不同。相反,我们会将 random.Next() 放入事件函数中,以便将该值保存到 Azure 表存储中,以便在后续重新运行时使用。编排器还可能正在等待正常函数创建的一些外部事件。例如,某人必须验证他们的电子邮件帐户,这可能需要几天的时间,这就是为什么持久函数可以在被事件触发时自行卸载并重新启动。

关于Azure Durable编排功能ILogger输出两次日志,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66171178/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com