簡體   English   中英

終止正在等待計時器的協調器 function 是否安全?

[英]Is it safe to terminate an orchestrator function that is waiting on a timer?

如果我在當前正在休眠並等待通過IDurableOrchestrationContext.CreateTimer創建的持久計時器的正在運行的協調器上調用IDurableOrchestrationClient.TerminateAsync ,這是否會導致包括計時器在內的整個進程正常關閉?

關於計時器的文檔有一個非常明確的警告,關於優雅取消在編排中未激活的任何計時器:

警告

如果您的代碼不會等待它完成,請使用 CancellationTokenSource (.NET) 或對返回的 TimerTask (JavaScript) 調用 cancel() 來取消持久計時器。 在所有未完成的任務完成或取消之前,持久任務框架不會將編排的狀態更改為“已完成”。

調用Terminate會遵守這些限制嗎? 它的文檔根本沒有說明這一點。

設想

我有一個要求,我需要在某個實例創建后“監視”它一段時間,並在實例被刪除后停止監視它。

現在,我的應用程序在創建和刪除實體時引發 EventGrid 事件,我在我的編排觸發器活動中收聽這些事件:一旦收到創建事件,我就啟動監視該實例的編排。 收到刪除事件后,我會向編排器發送一個外部事件,以表示它應該停止監視該實例並終止。 當然,每個創建/刪除對都由其自己的監視器處理(它們彼此隔離,由基於實體 ID 的顯式實例 ID 控制)。

編排器邏輯基本上觸發 2 個任務並等待第一個完成:

  1. 一個計時器,基於創建的實例中的數據。 這可能是幾分鍾,也可能是幾個月
  2. 等待觸發器 function 通知取消的WaitForExternalEvent

如果任務 2 獲勝,我取消計時器(根據建議),並退出 function。如果任務 1 獲勝,我在實例上執行我需要的處理並忽略外部事件。

協調器本身看起來像這樣:

    [FunctionName(nameof(StartExpirationTracking))]
    public async Task StartExpirationTracking(
        [OrchestrationTrigger] IDurableOrchestrationContext context)
    {
        var entity = context.GetInput<Entity>();

        using var cancellationTokenSource = new CancellationTokenSource();
        var expirationTimeTask = context.CreateTimer(entity.ExpirationDate, cancellationTokenSource.Token);
        var stopTrackingEventTask = context.WaitForExternalEvent("StopTracking");

        var winner = await Task.WhenAny(expirationTimeTask, stopTrackingEventTask);
        if (winner == stopTrackingEventTask)
        {
            cancellationTokenSource.Cancel();

            return;
        }

        await ProcessExpiration(entity);
    }

那么問題就變成了:與其發送外部事件並等待它終止編排,不如直接從觸發器調用 Terminate 是否安全?

這會稍微簡化我的邏輯,因為我不需要關心編排中的任何外部事件,並且可以這樣做:

    [FunctionName(nameof(StartExpirationTracking))]
    public async Task StartExpirationTracking(
        [OrchestrationTrigger] IDurableOrchestrationContext context)
    {
        var entity = context.GetInput<Entity>();

        await context.CreateTimer(entity.ExpirationDate, CancellationToken.None);
        await ProcessExpiration(entity);
    }

但我不確定在處理持久計時器時終止執行是否安全(我找不到任何相關信息)。 終止實例是否也會以優雅的方式終止計時器? 這種方法會以任何方式改變 function 使用/成本嗎? 或者我應該保留我的 ExternalEvent 方法以優雅地顯式取消執行嗎?

這是來自https://github.com/Azure/azure-functions-durable-extension/discussions/2115的更新交叉帖子

是的,終止編排是安全的,即使它有未完成的未決計時器(或未決活動或子編排調用,就此而言)。 業務流程將始終轉換為“已終止”state。實例終止后出現的任何消息(包括計時器消息)都將被靜默丟棄。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM