在开始之前,您必须考虑 Durable Functions 的真正工作原理。要了解流程,请看以下示例:
#r "Microsoft.Azure.WebJobs.Extensions.DurableTask"
public static async Task Run(DurableOrchestrationContext context, TraceWriter log)
{
await context.CallActivityAsync<string>("Hello1");
await context.CallActivityAsync<string>("Hello2");
}
运行时的工作方式如下:
- 它进入编排并命中第一个,其中调用
await
了一个活动Hello1
- 控件返回到一个名为Dispatcher的组件,该组件是框架的内部部分。它检查当前编排 ID 是否已调用此特定活动。如果不是,它会等待结果并释放编排使用的资源
- 等待
Task
完成后,调度程序重新创建编排并从头开始重播
- 它再次等待活动Hello1,但这一次在查阅编排历史后它知道,它已被调用并保存了结果 - 它使用保存的结果并继续执行
- 它达到了第二个
await
,整个循环又一次
正如您所看到的,在幕后需要执行一些严肃的工作。在将工作委派给编排和活动时,还有一个经验法则:
- 编排应该只编排 - 因为它有许多限制,例如单线程,只等待安全任务(这意味着DurableOrchestrationContext类型上可用的任务)并且在多个队列(而不是 VM)之间扩展。更重要的是它必须是幂等的(所以它不能使用例如
DateTime.Now
或直接查询数据库)
- 活动应该执行工作 - 它作为典型功能工作(没有编排限制)并扩展到多个不同的虚拟机
在您的场景中,您应该只执行一个活动,这将完成所有工作,而不是遍历编排中的记录(特别是因为您不能在编排中使用绑定到例如服务总线 - 但是您可以这样做活动,它可以获取数据,对其进行转换,然后推送到您想要的任何类型的服务)。所以在你的代码中你可以有这样的东西:
[FunctionName("Orchestration_Client")]
public static async Task<string> Orchestration_Client(
[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "start")] HttpRequestMessage input,
[OrchestrationClient] DurableOrchestrationClient starter)
{
return await starter.StartNewAsync("Orchestration", await input.Content.ReadAsStringAsync());
}
[FunctionName("Orchestration")]
public static async Task Orchestration_Start([OrchestrationTrigger] DurableOrchestrationContext context)
{
var payload = context.GetInput<string>();
await context.CallActivityAsync(nameof(Activity), payload);
}
[FunctionName("Activity")]
public static string Activity(
[ActivityTrigger] DurableActivityContext context,
[Table(TableName, Connection = "TableStorageConnectionName")] IAsyncCollector<FooEntity> foo)
{
// Get data from request
var payload = context.GetInput<string>();
// Fetch data from database
using(var conn = new SqlConnection())
...
// Transform it
foreach(var record in databaseResult)
{
// Do some work and push data
await foo.AddAsync(new FooEntity() { // Properties });
}
// Result
return $"Processed {count} records!!";
}
这更像是一个想法,而不是一个真实的例子,但你应该能够明白这一点。另一件事是,Durable Functions 是否真的是此类操作的最佳解决方案——我相信有更好的服务,例如 Azure 数据工厂。