使用 Azure Durable Functions 的即发即弃后台作业
Fire-and-forget background jobs using Azure Durable Functions
我有一个用例需要我在不关心其结果的情况下启动一些 Azure Durable Functions,我想知道我的方法是否正确。
这是我所处的场景:
- 函数
A
使用 HttpTrigger
- 函数
B
使用 ActivityTrigger
这是我的工作流程:
A
被调用,需要做一些业务逻辑
- 除了这个业务逻辑,我还需要做一个很长的后台任务,它可能会失败,也可能不会失败。我不关心结果,但每次
A
被调用时我都需要 运行 这个任务。
A
需要尽快 return,这就是为什么我等不及后台任务完成的原因
B
负责此后台任务,而 A
returns
我在网上找到的所有 Durable Functions 示例都是这样的:
await starter.StartNewAsync("BackgroundDurableFunction", data)
我的问题是,我不想 await
持久功能,但我需要它 运行 在后台执行它的操作(主要是网络 I/O ).
为了避免等待这个持久函数,我最终采用了这个解决方法:
Task.Factory.StartNew(() => starter.StartNewAsync("BackgroundDurableFunction", data));
这似乎工作得很好,因为我不需要 await
任何东西,但在阅读 The Dangers of Task.Factory.StartNew 之后我有点害怕这可能是一个危险的解决方案。
所以,问题是:启动 Durable Function 并将其 运行 放在后台而不关心其结果(并且没有关于不等待任务的警告)的正确方法是什么?
是的,持久函数应该适合您的场景。您只缺少一件事:Orchestrator。这应该让你开始:
[FunctionName("MyHttpTriggered")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", Route = null)] HttpRequest req, ILogger log,
[OrchestrationClient] DurableOrchestrationClient starter)
{
string data = "hello";
string instanceId = await starter.StartNewAsync("MyOrchestrator", data);
return new OkObjectResult($"Orchestrator started. Instance ID={instanceId}");
}
[FunctionName("MyOrchestrator")]
public static async Task MyOrchestrator(
[OrchestrationTrigger] DurableOrchestrationContext context, ILogger log)
{
string data = context.GetInput<string>();
await context.CallActivityAsync("YourActivityFunction", data);
}
[FunctionName("YourActivityFunction")]
public static async Task YourActivityFunction([ActivityTrigger] string data, ILogger log)
{
// do whatever here
}
虽然有 await
个声明,但这确实是即刻即弃。相反的是 fan-in 模式。在这种情况下,您基本上是在没有扇入的情况下进行扇出。
我有一个用例需要我在不关心其结果的情况下启动一些 Azure Durable Functions,我想知道我的方法是否正确。
这是我所处的场景:
- 函数
A
使用HttpTrigger
- 函数
B
使用ActivityTrigger
这是我的工作流程:
A
被调用,需要做一些业务逻辑- 除了这个业务逻辑,我还需要做一个很长的后台任务,它可能会失败,也可能不会失败。我不关心结果,但每次
A
被调用时我都需要 运行 这个任务。 A
需要尽快 return,这就是为什么我等不及后台任务完成的原因B
负责此后台任务,而A
returns
我在网上找到的所有 Durable Functions 示例都是这样的:
await starter.StartNewAsync("BackgroundDurableFunction", data)
我的问题是,我不想 await
持久功能,但我需要它 运行 在后台执行它的操作(主要是网络 I/O ).
为了避免等待这个持久函数,我最终采用了这个解决方法:
Task.Factory.StartNew(() => starter.StartNewAsync("BackgroundDurableFunction", data));
这似乎工作得很好,因为我不需要 await
任何东西,但在阅读 The Dangers of Task.Factory.StartNew 之后我有点害怕这可能是一个危险的解决方案。
所以,问题是:启动 Durable Function 并将其 运行 放在后台而不关心其结果(并且没有关于不等待任务的警告)的正确方法是什么?
是的,持久函数应该适合您的场景。您只缺少一件事:Orchestrator。这应该让你开始:
[FunctionName("MyHttpTriggered")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", Route = null)] HttpRequest req, ILogger log,
[OrchestrationClient] DurableOrchestrationClient starter)
{
string data = "hello";
string instanceId = await starter.StartNewAsync("MyOrchestrator", data);
return new OkObjectResult($"Orchestrator started. Instance ID={instanceId}");
}
[FunctionName("MyOrchestrator")]
public static async Task MyOrchestrator(
[OrchestrationTrigger] DurableOrchestrationContext context, ILogger log)
{
string data = context.GetInput<string>();
await context.CallActivityAsync("YourActivityFunction", data);
}
[FunctionName("YourActivityFunction")]
public static async Task YourActivityFunction([ActivityTrigger] string data, ILogger log)
{
// do whatever here
}
虽然有 await
个声明,但这确实是即刻即弃。相反的是 fan-in 模式。在这种情况下,您基本上是在没有扇入的情况下进行扇出。