[英]How to terminate a Durable orchestration with custom status in Azure Durable Functions
[英]How to execute a lot of durable functions triggered by Azure Queue?
簡而言之,我們的任務是處理大量輸入消息。
為了解決這個問題,我們決定使用 Azure 隊列存儲和 Azure Functions。 我們有類似於以下代碼的 Azure Functions 結構:
隊列觸發功能
[FunctionName("MessageControllerExecutor")]
public static async void Run(
[QueueTrigger(QUEUE_NAME, Connection = QUEUE_CONNECTION_NAME)]string queueMessage,
[OrchestrationClient] DurableOrchestrationClient client,
TraceWriter log)
{
await client.StartNewAsync("MessageController", queueMessage);
}
耐用功能
[FunctionName("MessageController")]
public static async void Run(
[OrchestrationTrigger] DurableOrchestrationContext context,
TraceWriter log)
{
if (!context.IsReplaying) log.Warning("MessageController started");
var function1ResultTask = context.CallActivityAsync<ResultMessage>("Function_1", new InputMessage());
var function2ResultTask = context.CallActivityAsync<ResultMessage>("Function_2", new InputMessage());
await Task.WhenAll(function1ResultTask, function2ResultTask);
// process Function_1 and Function_2 results
// ...
}
簡單活動函數示例
[FunctionName("Function_1")]
public static ResultMessage Run(
[ActivityTrigger] DurableActivityContext activityContext,
TraceWriter log)
{
var msg = activityContext.GetInput<InputMessage>();
int time = new Random().Next(1, 3);
Thread.Sleep(time * 1000);
return new ResultMessage()
{
Payload = $"Function_1 slept for {time} sec"
};
}
MessageControllerExecutor
在隊列中接收到新項目時觸發。 MessageController
是一個 Durable Function,它使用一些簡單的活動函數來處理每條消息。
當我們將消息推送到隊列時, MessageControllerExecutor
函數會立即啟動並異步觸發MessageController
並傳遞消息,因此這按預期工作。
但是我們面臨着這個問題。 並非所有MessageController
函數實例都運行。
例如,我們將 100 條消息推送到隊列中,但只有大約 10-20% 的消息被MessageController
處理。
某些消息未處理或處理延遲很長時間。 看起來持久函數未能啟動 б,盡管沒有拋出異常。
我們有幾個問題:
為了我理解的簡潔起見,您確實從上面的問題中的編排觸發器中刪除了一些代碼,但是在await Task.WhenAll(...)
之后您到底在做什么? 如果它包含任何類型的重要處理,您應該真正將其分配給第三個操作函數(例如Function_3
)來執行,然后簡單地從編排函數返回結果。
更新:我剛剛注意到你的函數被定義為async void
。 如果我不得不猜測,這實際上會導致運行時出現問題。 您可以嘗試將其更改為async Task
並查看您的問題是否消失嗎? 作為一般規則,在 .NET 中async void
將方法定義為async void
。
德魯答案的一些擴展。 正如文檔所述,您不應使用 Thread.Sleep(),而應使用 CreateTimer Api。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.