概觀
工作流程中的執行者通常是有狀態的——例如,它們可能累積訊息、追蹤周轉次數,或快取中間結果。 當工作流程在多個執行過程中重複使用並共用執行執行器實例時,前一次執行的殘留狀態可能會洩漏到後續執行中,導致意外行為或資料損壞。
介面 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() 。 序列如下:
- 取得所有權 — 當工作流程執行開始時,執行時會取得工作流程實例的所有權,並記錄哪些執行器需要重置。
- 運行執行 — 執行者處理訊息並可能累積狀態。
-
所有權釋放 — 當執行完成(或被處置)時,執行時會釋放所有實作
ResetAsync()的共享執行者實例的所有權與呼叫IResettableExecutor。 - 準備重用 — 成功重置後,工作流程可用於新一輪。
若任何共享執行器未能重置(因為未實作介面),該工作流程將被標記為不可重用,後續執行將拋棄。
與國家隔離的關係
IResettableExecutor 補充了 State Management 中描述的輔助方法模式。 這兩種方法滿足不同需求:
- 輔助方法 (每次執行建立新實例)提供最強的隔離保證,並被推薦作為預設方法。
-
IResettableExecutor當你需要在多次執行間共享執行器實例時,這會非常有用,例如在執行器建構成本高昂,或某個工作流程作為代理公開並在多次呼叫中重複使用時。
選擇最適合你情況的方法。 對大多數工作流程來說,輔助方法就足夠了。 在分享實例時使用 IResettableExecutor 是刻意的設計選擇。
這個概念不適用於 Python。 為了完整狀態隔離,為每個獨立執行建立新的工作流程和執行器實例。 請參閱 狀態管理 部分以了解模式與範例。