Režimy provádění pracovního postupu

Při spuštění pracovního postupu v .NET řídí režim spouštění způsob zpracování superkroků a způsob doručení událostí příjemci. Třída InProcessExecution zveřejňuje dva režimy spuštění: OffThread a Lockstep.

Přehled

OffThread (výchozí) Lockstep
Provádění superstepu Vlákno na pozadí Vlákno spotřebitele
Doručování událostí Okamžitě, když jsou události vyvolány Dávkování po dokončení každého superkroku
Provedení kroku Nezávislé na zpracování událostí Pozastaveno, dokud se nespotřebují dávkové události.
Souběžnost Uživatel čte události při spouštění superkroků Alternativní spuštění příjemce a superkroku
Nejlepší pro Streamování v reálném čase, produkční scénáře Testování, ladění, deterministické řazení

OffThread

OffThread je výchozí režim spuštění. Supersteps běží na vlákně na pozadí a události se streamují okamžitě, protože jsou vyvolány prostřednictvím implementace založené na kanálu.

// OffThread is the default — these are equivalent:
await using StreamingRun run = await InProcessExecution.RunStreamingAsync(workflow, input);
await using StreamingRun run = await InProcessExecution.OffThread.RunStreamingAsync(workflow, input);

Jak to funguje

  1. Úloha na pozadí běží nepřetržitě, zatímco zprávy čekají na vyřízení.
  2. Vzhledem k tomu, že exekutory poskytují výstupy nebo události, výsledné WorkflowEvent objekty se zapisují do nevázaného objektu Channel<WorkflowEvent>.
  3. Příjemce čte události z kanálu prostřednictvím WatchStreamAsync, přijímá je v reálném čase, jak jsou produkovány.
  4. Po dokončení všech superkroků a pokud nezůstanou žádné zprávy, spuštění se zastaví se stavem Idle nebo PendingRequests.

Vzhledem k tomu, že se smyčka superstep a příjemce spouští souběžně, události se zobrazí hned po jejich vyvolání – zpoždění ukládání do vyrovnávací paměti neexistuje. OffThread je ideální pro scénáře streamování, ve kterých záleží na doručování událostí s nízkou latencí, jako je zobrazení aktualizací tokenů po tokenech v uživatelském rozhraní.

Souběžná spuštění

OffThread také podporuje souběžnou variantu, která umožňuje více spuštěním sdílet stejnou instanci pracovního postupu současně:

await using StreamingRun run = await InProcessExecution.Concurrent.RunStreamingAsync(workflow, input);

Důležité

Souběžné spuštění vyžaduje, aby všechny exekutory v pracovním postupu byly deklarovány crossRunShareable (v konstruktoru) nebo aby byly poskytovány jako metody továrny.

Lockstep

V režimu Lockstep se superkroky spouští ve vlákně spotřebitele, nikoli v úloze na pozadí. Události se shromažďují během každého superstepu a po dokončení superstepu se emitují v jednom balíku.

await using StreamingRun run = await InProcessExecution.Lockstep.RunStreamingAsync(workflow, input);

Jak to funguje

  1. Příjemce volá WatchStreamAsync, který řídí spouštěcí smyčku.
  2. Superkrok běží do dokončení a události se hromadí ve frontě.
  3. Po dokončení superkroku se všechny události zařazené do fronty předají příjemci.
  4. Další superkrok začíná teprve poté, co spotřebitel obdrží všechny události z předchozího kroku.

Tento střídavý vzorec znamená, že spotřebitel a modul pracovního postupu nikdy neběží současně. Doručování událostí je deterministické – je zaručeno, že všechny události z jednoho superkroku dorazí před všemi událostmi z následujícího superkroku.

Kdy použít Lockstep

Lockstep je užitečný v následujících případech:

  • Testování – deterministické řazení událostí usnadňuje aserce.
  • Ladění — krokové ladění je jednodušší, když běh programu zůstává na vlákně spotřebitele.
  • Seřazené zpracování – scénáře, kdy potřebujete plně zpracovat události jednoho superkroku před zahájením dalšího superkroku.

Volba režimu spuštění

Pro většinu produkčních scénářů se doporučuje výchozí režim OffThread . Poskytuje nejlepší odezvu a umožňuje pracovnímu postupu pokračovat ve zpracování, zatímco příjemce zpracovává události.

Lockstep použijte, pokud je deterministické chování důležitější než výkon, například při jednotkových testech nebo ladicích relacích.

// Production: OffThread (default)
await using StreamingRun run = await InProcessExecution.RunStreamingAsync(workflow, input);

// Testing: Lockstep for deterministic behavior
await using StreamingRun run = await InProcessExecution.Lockstep.RunStreamingAsync(workflow, input);

Provádění bez streamování

Oba režimy provádění podporují provádění bez streamování prostřednictvím RunAsync. V režimu bez streamování se pracovní postup spustí k dokončení a shromažďuje všechny události do objektu Run , nikoli je postupně streamuje:

Run run = await InProcessExecution.RunAsync(workflow, input);

// Access all emitted events
foreach (WorkflowEvent evt in run.OutgoingEvents)
{
    // Process events
}

Vzhledem k tomu, že provádění bez streamování shromažďuje všechny události až po dokončení, výhoda doručení událostí v reálném čase, kterou poskytuje OffThread, zde neplatí. Hlavní rozdíl mezi režimy v nesíťových scénářích je způsob zpracování vláken: OffThread spouští superkroky na pozadí, čímž uvolňuje vlákno volajícího, zatímco čeká na dokončení. Naproti tomu Lockstep spouští superkroky na vlákně volajícího, což ho blokuje, dokud se pracovní postup nedokončí.

Provádění bez streamování používá výchozí režim OffThread. Použití Lockstepu s prováděním bez streamování:

Run run = await InProcessExecution.Lockstep.RunAsync(workflow, input);

Další kroky

Režimy spouštění se nevztahují na pracovní postupy Pythonu. Pracovní postupy Pythonu používají jeden model provádění, který zpracovává zpracování superstepu a doručování událostí prostřednictvím asynchronního generátoru. Tento model je podobný režimu lockstepu .NET – kroky se neposouvají, pokud uživatel aktivně neodebírá události z generátoru.

Informace o spouštění pracovních postupů Pythonu najdete v tématu Tvůrce pracovních postupů a spouštění pracovních postupů.

Při spuštění pracovního postupu v Go řídí spouštěcí prostředí způsob zpracování superkroků a způsob doručení událostí příjemci. Balíček workflow/inproc zveřejňuje tři prostředí: Default/OffThread, Lockstepa .Concurrent

Přehled

OffThread / Výchozí Lockstep Souběžný
Provádění superstepu goroutine na pozadí Řízený příjemcem událostí Goroutine na pozadí
Doručování událostí Okamžitě, když jsou události vyvolány Zpracováváno dávkově při čtení streamu Okamžitě, když jsou události vyvolány
Nejlepší pro Streamování v reálném čase, produkční scénáře Testování, ladění, deterministické řazení Sdílené instance pracovních postupů s souběžnými bezpečnými vazbami

OffThread

OffThread je výchozí režim spuštění. Jsou to ekvivalenty:

stream, err := inproc.Default.RunStreaming(ctx, wf, input)
stream, err := inproc.OffThread.RunStreaming(ctx, wf, input)

Jak to funguje

  1. Goroutine na pozadí provádí superkroky, dokud zprávy čekají na zpracování.
  2. Vzhledem k tomu, že exekutory poskytují výstupy nebo události, události pracovního postupu se zapisují do datového proudu.
  3. Konzument čte události pomocí WatchStream, přičemž je přijímá v okamžiku, kdy vznikají.
  4. Když jsou všechny superkroky dokončeny a nezbývají žádné zprávy, běh se zastaví ve stavu nečinnosti nebo čekajícího požadavku.

Souběžná spuštění

Použijte inproc.Concurrent , když všechny vazby exekutoru v pracovním postupu podporují souběžné sdílené spouštění:

stream, err := inproc.Concurrent.RunStreaming(ctx, wf, input)
if err != nil {
    return err
}
defer stream.Close(ctx)

Lockstep

V režimu Lockstep postupuje provádění workflow podle toho, jak konzument čte ze streamu. Díky tomu je řazení událostí deterministické pro testy a ladění.

stream, err := inproc.Lockstep.RunStreaming(ctx, wf, input)
if err != nil {
    return err
}
defer stream.Close(ctx)

for evt, err := range stream.WatchStream(ctx) {
    if err != nil {
        return err
    }
    // inspect event
}

Jak to funguje

  1. Příjemce volá WatchStream, který řídí spouštěcí smyčku.
  2. Superkrok proběhne až do dokončení a události se akumulují.
  3. Nahromaděné události se předávají příjemci.
  4. Další superkrok začne teprve poté, co příjemce obdrží události z předchozího superkroku.

Kdy použít Lockstep

Lockstep použijte, pokud je deterministické chování důležitější než streamování s nízkou latencí, jako jsou testy jednotek, ladění nebo scénáře, kdy chcete plně zpracovat události jednoho superkroku před zahájením dalšího superkroku.

Volba režimu spuštění

Pro většinu produkčních scénářů použijte inproc.Default nebo inproc.OffThread. Používá inproc.Lockstep se, když je deterministické řazení událostí důležitější než latence streamování, například v testech. Používejte inproc.Concurrent pouze v případech, kdy každá vazba v pracovním postupu podporuje souběžné sdílené spouštění.

// Production: OffThread (default)
stream, err := inproc.Default.RunStreaming(ctx, wf, input)
if err != nil {
    return err
}
defer stream.Close(ctx)

// Testing: Lockstep for deterministic behavior
testStream, err := inproc.Lockstep.RunStreaming(ctx, wf, input)
if err != nil {
    return err
}
defer testStream.Close(ctx)

Provádění bez streamování

Všechna prostředí pro spuštění také podporují režim bez streamování Run, který se provádí až do dalšího zastavení a ukládá generované události do vráceného běhu.

run, err := inproc.Default.Run(ctx, wf, input)
if err != nil {
    return err
}

for evt := range run.NewEvents() {
    if output, ok := evt.(workflow.OutputEvent); ok {
        fmt.Printf("Final result: %v\n", output.Output)
    }
}

Další kroky