Visszaállítható végrehajtók

Áttekintés

A munkafolyamatok végrehajtói gyakran állapotalapúak – például üzeneteket halmozhatnak fel, nyomon követhetik a fordulószámokat, vagy gyorsítótárazhatják a köztes eredményeket. Ha egy munkafolyamatot több futtatás során használnak fel megosztott végrehajtópéldányokkal, az előző futtatásból származó hátrahagyott állapot a későbbi futtatásokba szivároghat, ami váratlan viselkedést vagy adatsérülést okozhat.

Az IResettableExecutor interfész ezt úgy oldja meg, hogy szerződést ad a végrehajtóknak a futtatások közötti belső állapotuk törlésére. A munkafolyamat-futtatókörnyezet automatikusan meghívja ResetAsync() a megosztott végrehajtó példányokon, amikor a futtatás véget ér, biztosítva, hogy a következő futtatás tiszta lappal kezdhető.

A probléma

Fontolja meg egy olyan végrehajtót, amely üzeneteket gyűjt egy munkafolyamat futtatása során:

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

Ha ez a végrehajtó meg van osztva a munkafolyamat-futtatások között, _messages megőrzi az előző futtatás adatait. A második futtatás során olyan régi üzenetek jelenhetnek meg, amelyek nem tartoznak oda.

Az IResettableExecutor interfész

IResettableExecutor egyetlen metódust határoz meg, amelyet a munkafolyamat futtatókörnyezete a futtatások között hív meg:

public interface IResettableExecutor
{
    ValueTask ResetAsync();
}

Amikor egy végrehajtó implementálja ezt a felületet, a futtatókörnyezet minden futtatás után biztonságosan alaphelyzetbe állíthatja azt, így a munkafolyamat elavult állapot nélkül újra felhasználható.

Az IResettableExecutor implementálása

Állapotú végrehajtó visszaállíthatóságának érdekében implementálja a felületet, és törölje az összes módosítható állapotot a következőben 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;
    }
}

A visszaállítható végrehajtókat használó munkafolyamat teljes munka példáját a WorkflowAsAnAgent mintában találhatja meg.

Mikor kell implementálni?

Nem minden végrehajtónak kell implementálnia IResettableExecutor. Használja ezt a döntési útmutatót:

Scenario Végrehajtása? Jogcím
A végrehajtó mutable állapotú (listák, számlálók, gyorsítótárak), és futtatások között van megosztva Igen Az egyik futtatás adatállapotának kiszivárgása a következőbe
A végrehajtó állapot nélküli No Nincs mit alaphelyzetbe állítani
A végrehajtót munkafolyamatonként frissen hozza létre (gyári módszerrel) No Minden futtatás tiszta állapotú új példányt kap
Executor több futási cikluson keresztül megoszthatóként van deklarálva (declareCrossRunShareable: true) No A többfuttatásos megosztható végrehajtók támogatják az egyidejű használatot alaphelyzetbe állítás nélkül

Figyelmeztetés

Ha egy megosztott állapotalapú végrehajtó nem implementál IResettableExecutor, a munkafolyamat újbóli használata a következőt InvalidOperationExceptioneredményezi:

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

Hogyan használja a futtatókörnyezet azt?

A munkafolyamat-futtatókörnyezet automatikusan kezeli az alaphelyzetbe állítási életciklust. Nem kell saját maga indítania a ResetAsync() hívását. A sorrend a következő:

  1. A tulajdonjog megszerzése – amikor egy munkafolyamat-futtatás elindul, a futtatókörnyezet átveszi a munkafolyamat-példány tulajdonjogát, és megjelöli, hogy mely végrehajtók igényelnek alaphelyzetbe állítást.
  2. Futtatás — a végrehajtók feldolgozzák az üzeneteket, és az állapot felhalmozódhat.
  3. A tulajdonjog felszabadítva – amikor a futtatás befejeződik (vagy megsemmisítésre kerül), a futtatókörnyezet kiadja a tulajdonjogot, és meghívja ResetAsync() az összes megosztott végrehajtópéldányt, amelyek implementálják a IResettableExecutor-t.
  4. Újra felhasználható – a sikeres visszaállítás után a munkafolyamat új futtatáshoz használható.

Ha egy megosztott végrehajtó nem tud alaphelyzetbe állítani (mert nem implementálja a felületet), a munkafolyamat nem újrafelhasználhatóként van megjelölve, és az azt követő futtatások elindulnak.

Kapcsolat az állapotelkülönítéshez

IResettableExecutor kiegészíti az állapotkezelésben leírt segédmetódus-mintát. A két megközelítés különböző igényeket szolgál ki:

  • A segítő módszerek (futtatásonként új példányok létrehozása) biztosítják a legerősebb elkülönítési garanciákat, és alapértelmezett megközelítésként ajánlottak.
  • IResettableExecutor Akkor hasznos, ha a futtatások között meg kell osztania a végrehajtópéldányokat – például akkor, ha a végrehajtó felépítése költséges, vagy ha egy munkafolyamat ügynökként van közzétéve, és több hívással újra felhasználható.

Válassza ki a forgatókönyvnek leginkább megfelelő megközelítést. A legtöbb munkafolyamathoz elegendő a segédmetenek használata. Használja a IResettableExecutor-t, amikor a példányok megosztása szándékos tervezési döntés.

Ez a fogalom nem vonatkozik a Pythonra. Az állapot teljes elkülönítéséhez hozzon létre új munkafolyamatokat és végrehajtópéldányokat minden független futtatáshoz. Példákat és mintákat az Állapotkezelésben talál.

Következő lépések