【发布时间】:2019-07-15 19:37:16
【问题描述】:
我编写了一个 Durable Function 编排器函数,其主要工作是平均扇出 1,000 个并行活动。由于这些活动的完成是前端用户在技术上等待的事情,因此我希望能够在活动仍在运行时查询进度(在前端显示进度条)。
以下是当前编排器代码的一部分,但我怀疑它是否符合编排器功能的约束 (https://docs.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-checkpointing-and-replay#orchestrator-code-constraints)。
基本上,如果 DF 框架将协调器重放到每个等待,这感觉就像它处理的等待数量不合理:
var replicationTasks = new List<Task<ReplicationOutput>>();
var replicationResults = new List<ReplicationOutput>();
// start up each simulation
for (int i = 0; i < inputs.NumberOfReplications; i++)
{
var replicationInput = new ReplicationInput();
var task = context.CallActivityAsync<ReplicationOutput>("SimulationOrchestrator_SimulateReplication", replicationInput);
replicationTasks.Add(task);
}
// set initial custom status
var progress = new Progress();
progress.NumberCompleted = 0;
progress.Total = inputs.NumberOfReplications;
progress.TimeStarted = context.CurrentUtcDateTime;
progress.ElapsedTime = context.CurrentUtcDateTime.Subtract(progress.TimeStarted);
context.SetCustomStatus(progress);
// as each task finishes
while (replicationTasks.Any())
{
Task<ReplicationOutput> nextFinished = await Task.WhenAny(replicationTasks);
replicationTasks.Remove(nextFinished);
replicationResults.Add(await nextFinished);
// update progress object and custom status
progress.NumberCompleted++;
progress.ElapsedTime = context.CurrentUtcDateTime.Subtract(progress.TimeStarted);
context.SetCustomStatus(progress);
}
// aggregate replications together into a single set of results
return new Results(replicationResults);
这在简单的测试条件下不一定会失败,但协调器文档(相当积极地)警告说要保持历史表清晰,避免等待/阻塞等。
是否有记录或“最佳实践”的方法来实现可查询进度的目标?我见过的所有扇出/扇入示例仅使用 await Task.WhenAll(replicationTasks) 仅在 所有 任务完成后继续,我认为这不会允许增量进度检查。
【问题讨论】:
-
据我所知,这是 DF 中的一个主要差距,并且在某处没有提到最佳实践。对于一个项目,我们通过 Azure Sql Db 中的 Serilog 批量批量插入创建了一个用于大规模扇出 >5k 的状态日志记录。在不同的解决方案中,我们目前正试图通过新的 DurableEntities 实现某种状态。每个活动(按实例)在实体中保存一个状态。因此,您可以实时查询所有实体以了解您的活动。也许这有帮助。
标签: c# asynchronous aggregate monitoring azure-durable-functions