Sdílet prostřednictvím


Resetovatelné vykonavatele

Přehled

Exekutory v pracovních postupech jsou často stavové – například můžou shromažďovat zprávy, sledovat počty turnů nebo ukládat průběžné výsledky do mezipaměti. Když se pracovní postup znovu použije ve více spuštěních s instancemi sdíleného exekutoru, může do následných spuštění dojít k úniku stavu z předchozího spuštění, což způsobí neočekávané chování nebo poškození dat.

Rozhraní IResettableExecutor to řeší poskytnutím smlouvy exekutorům k vymazání jejich interního stavu mezi spuštěními. Modul runtime pracovního postupu automaticky volá metodu ResetAsync() na instancích sdíleného vykonavatele po dokončení spuštění a zajišťuje čistý stav pro další spuštění.

Problém

Zvažte prováděče, který shromažďuje zprávy během spuštění pracovního postupu:

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...
    }
}

Pokud je tento exekutor sdílen napříč spuštěními pracovního postupu, _messages uchovává data z předchozího spuštění. Druhé spuštění by mohlo narazit na zastaralé zprávy, které do něj nepatří.

Rozhraní IResettableExecutor

IResettableExecutor definuje jednu metodu, kterou modul runtime pracovního postupu volá mezi spuštěními:

public interface IResettableExecutor
{
    ValueTask ResetAsync();
}

Když exekutor implementuje toto rozhraní, modul runtime ho může po každém spuštění bezpečně resetovat, což umožňuje opakované použití pracovního postupu bez zastaralého stavu.

Implementace IResettableExecutor

Chcete-li vytvořit stavový exekutor resetovatelný, implementujte rozhraní a vymažte veškerý proměnlivý stav v 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;
    }
}

Kompletní funkční příklad pracovního postupu, který používá resetovatelné exekutory, najdete v ukázce WorkflowAsAnAgent.

Kdy implementovat

Ne všechny exekutory musí implementovat IResettableExecutor. Použijte tohoto průvodce rozhodováním:

Scénář Implementovat? Reason
Exekutor má proměnlivý stav (seznamy, čítače, mezipaměti) a sdílí se napříč spuštěními. Ano Stav z jednoho běhu programu by unikl do dalšího
Exekutor je bezstavový Ne Není co resetovat.
Exekutor je vytvořen čerstvě pro pracovní postup (prostřednictvím tovární metody). Ne Každé spuštění získá novou instanci s čistým stavem.
Exekutor je deklarován jako sdíletelné mezi různými spuštěními (declareCrossRunShareable: true) Ne Exekutory s možností sdílení napříč spuštěními podporují souběžné použití bez resetování.

Výstraha

Pokud sdílený stavový exekutor neimplementuje IResettableExecutor, opětovné spuštění pracovního postupu vyvolá následující:InvalidOperationException

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

Jak ho modul runtime používá

Modul runtime pracovního postupu spravuje životní cyklus resetování automaticky. Nemusíte volat ResetAsync() sami. Posloupnost je:

  1. Vlastnictví získané – při spuštění pracovního postupu modul runtime převezme vlastnictví instance pracovního postupu a označí, které exekutory je třeba resetovat.
  2. Spouštění se provádí – exekutoři zpracovávají zprávy a mohou akumulovat stav.
  3. Vlastnictví uvolněno – když se spuštění dokončí (nebo je ukončeno), runtime modul uvolní vlastnictví a zavolá ResetAsync() na všechny instance sdíleného exekutoru, které implementují IResettableExecutor.
  4. Připraveno k opakovanému použití – po úspěšném resetování lze pracovní postup použít pro nové spuštění.

Pokud se některému sdílenému exekutoru nepodaří resetovat (protože neimplementuje rozhraní), pracovní postup se označí jako nereusovatelný a následné spuštění se vyvolá.

Vztah k izolaci stavu

IResettableExecutor doplňuje vzor pomocných metod popsaný ve State Management. Dva přístupy slouží různým potřebám:

  • Pomocné metody (vytváření nových instancí při každém spuštění) poskytují nejsilnější záruky izolace a je doporučeno jako výchozí přístup.
  • IResettableExecutor je užitečné, když potřebujete sdílet instance exekutoru napříč spuštěními – například když je konstrukce exekutoru nákladná nebo když je pracovní postup vystavený jako agent a znovu je použit v rámci několika vyvolání.

Zvolte přístup, který nejlépe vyhovuje vašemu scénáři. U většiny pracovních postupů jsou pomocné metody dostatečné. Použití IResettableExecutor při sdílení instancí je záměrnou volbou návrhu.

Tento koncept se nevztahuje na Python. Pro úplnou izolaci stavu vytvořte pro každé nezávislé spuštění nové instance pracovního postupu a exekutoru. Vzory a příklady najdete v tématu Správa stavů .

Další kroky