共用方式為


可重設執行者

概觀

工作流程中的執行者通常是有狀態的——例如,它們可能累積訊息、追蹤周轉次數,或快取中間結果。 當工作流程在多個執行過程中重複使用並共用執行執行器實例時,前一次執行的殘留狀態可能會洩漏到後續執行中,導致意外行為或資料損壞。

介面 IResettableExecutor 透過提供執行者合約來解決此問題,讓執行者在執行間清除內部狀態。 當執行完成時,工作流程執行時會自動呼叫 ResetAsync() 共享執行器實例,確保下一次執行有乾淨的起點。

問題

考慮一個執行器在工作流程執行中收集訊息:

internal sealed partial class AggregationExecutor() : Executor("AggregationExecutor")
{
    private readonly List<string> _messages = [];

    [MessageHandler]
    private async ValueTask HandleAsync(string message, IWorkflowContext context)
    {
        this._messages.Add(message);
        // Process aggregated messages...
    }
}

如果這個執行器在多個工作流程執行中是共用的,則 _messages 會保留前一次執行的資料。 第二次運行時會看到不屬於它的陳舊訊息。

IResettableExecutor 介面

IResettableExecutor 定義了工作流程執行時在執行間呼叫的單一方法:

public interface IResettableExecutor
{
    ValueTask ResetAsync();
}

當執行者實作此介面時,執行時可在每次執行後安全重置介面,讓工作流程能在不出現過時狀態的情況下重用。

實作 IResettableExecutor

要讓狀態執行器可以重置,請實作相關介面並清除所有可變狀態:ResetAsync()

internal sealed partial class AggregationExecutor()
    : Executor("AggregationExecutor"), IResettableExecutor
{
    private readonly List<string> _messages = [];

    [MessageHandler]
    private async ValueTask HandleAsync(string message, IWorkflowContext context)
    {
        this._messages.Add(message);
        // Process aggregated messages...
    }

    public ValueTask ResetAsync()
    {
        this._messages.Clear();
        return default;
    }
}

欲了解使用可重置執行器的完整工作流程範例,請參見 WorkflowAsAnAgent 範例

何時實施

並非所有執行人都需要實作 IResettableExecutor。 請參考這份決策指南:

Scenario 實施? Reason
執行者具有可變狀態(清單、計數器、快取),且在執行過程中共享 是的 一次運行的狀態會洩漏到下一次
遺囑執行人是無國籍的 No 沒有什麼需要重置的
執行者會依工作流程重新建立(透過工廠方法) No 每次執行都會得到一個初始化為乾淨狀態的新實體
執行者被宣告為跨運行可共享(declareCrossRunShareable: true No 跨運行可共享執行者支援並行使用且不重置

警告

若共享有狀態執行器未實作IResettableExecutor,重用該工作流程會拋出:InvalidOperationException

"Cannot reuse Workflow with shared Executor instances that do not implement IResettableExecutor."

執行時如何使用它

工作流程執行時會自動管理重置生命週期。 你不需要自己呼叫 ResetAsync() 。 序列如下:

  1. 取得所有權 — 當工作流程執行開始時,執行時會取得工作流程實例的所有權,並記錄哪些執行器需要重置。
  2. 運行執行 — 執行者處理訊息並可能累積狀態。
  3. 所有權釋放 — 當執行完成(或被處置)時,執行時會釋放所有實作 ResetAsync()的共享執行者實例的所有權與呼叫IResettableExecutor
  4. 準備重用 — 成功重置後,工作流程可用於新一輪。

若任何共享執行器未能重置(因為未實作介面),該工作流程將被標記為不可重用,後續執行將拋棄。

與國家隔離的關係

IResettableExecutor 補充了 State Management 中描述的輔助方法模式。 這兩種方法滿足不同需求:

  • 輔助方法 (每次執行建立新實例)提供最強的隔離保證,並被推薦作為預設方法。
  • IResettableExecutor 當你需要在多次執行間共享執行器實例時,這會非常有用,例如在執行器建構成本高昂,或某個工作流程作為代理公開並在多次呼叫中重複使用時。

選擇最適合你情況的方法。 對大多數工作流程來說,輔助方法就足夠了。 在分享實例時使用 IResettableExecutor 是刻意的設計選擇。

這個概念不適用於 Python。 為了完整狀態隔離,為每個獨立執行建立新的工作流程和執行器實例。 請參閱 狀態管理 部分以了解模式與範例。

下一步