Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Quando si esegue un flusso di lavoro in .NET, la modalità di esecuzione controlla come vengono elaborati i superstep e il modo in cui gli eventi vengono recapitati al consumer. La InProcessExecution classe espone due modalità di esecuzione: OffThread e Lockstep.
Overview
| OffThread (impostazione predefinita) | Lockstep | |
|---|---|---|
| Esecuzione dei superstep | Thread in background | Thread del consumer |
| Recapito di eventi | Immediata, quando vengono generati gli eventi | In batch dopo il completamento di ogni superstep |
| Esecuzione dei passaggi | Indipendentemente dall'elaborazione degli eventi | In pausa fino all'utilizzo degli eventi in batch |
| Concorrenza | Il consumer legge gli eventi durante l'esecuzione dei superstep | L'esecuzione del consumer e dei superstep si alterna |
| Migliore per | Streaming in tempo reale, scenari di produzione | Test, correzione di errori, ordinamento deterministico |
OffThread
OffThread è la modalità di esecuzione predefinita . I superstep vengono eseguiti in un thread in background e gli eventi vengono trasmessi immediatamente quando vengono generati tramite un'implementazione basata su canale.
// 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);
Come funziona
- Un'attività in background esegue continuamente i superstep mentre sono presenti messaggi in sospeso.
- Poiché gli executor producono output o eventi, gli oggetti risultanti
WorkflowEventvengono scritti in unChannel<WorkflowEvent>illimitato. - Il consumer legge gli eventi dal canale tramite
WatchStreamAsync, ricevendoli in tempo reale man mano che vengono prodotti. - Quando tutti i superpassi sono completi e non rimangono messaggi, l'esecuzione si interrompe con uno stato
IdleoPendingRequests.
Poiché il ciclo superstep e il consumer vengono eseguiti simultaneamente, gli eventi vengono visualizzati non appena vengono generati, senza alcun ritardo di buffering. Questo rende OffThread ideale per scenari di streaming in cui il recapito di eventi a bassa latenza è importante, ad esempio la visualizzazione degli aggiornamenti token per token in un'interfaccia utente.
Esecuzioni simultanee
OffThread supporta anche una variante simultanea che consente a più esecuzioni di condividere contemporaneamente la stessa istanza del flusso di lavoro:
await using StreamingRun run = await InProcessExecution.Concurrent.RunStreamingAsync(workflow, input);
Importante
L'esecuzione simultanea richiede che tutti gli executor nel flusso di lavoro siano dichiarati crossRunShareable (nel costruttore) o vengano forniti come metodi factory.
Lockstep
In modalità Lockstep, i superstep vengono eseguiti nel thread del consumer anziché in un'attività in background. Gli eventi vengono accumulati durante ogni superpasso e rilasciati come un lotto al termine del superpasso.
await using StreamingRun run = await InProcessExecution.Lockstep.RunStreamingAsync(workflow, input);
Come funziona
- Il consumer chiama
WatchStreamAsync, che avvia il ciclo di esecuzione. - Un superstep viene eseguito fino al completamento e gli eventi vengono accumulati in una coda.
- Al termine del superstep, tutti gli eventi in coda vengono restituiti al consumer.
- Il superstep successivo inizia solo dopo che il consumer ha ricevuto tutti gli eventi di quello precedente.
Lo schema alternato implica che il consumer e il motore del flusso di lavoro non siano mai attivi contemporaneamente. Il recapito degli eventi è deterministico: è garantito che tutti gli eventi di un superstep arrivino prima di qualsiasi evento del superstep successivo.
Quando usare Lockstep
Lockstep è utile quando:
- Test : l'ordinamento deterministico degli eventi rende le asserzioni semplici.
- Debug: il debug con esecuzione passo-passo è più semplice quando l'esecuzione rimane nel thread del consumer.
- Elaborazione ordinata : scenari in cui è necessario elaborare completamente gli eventi di un superstep prima dell'inizio del passaggio successivo.
Scelta di una modalità di esecuzione
Per la maggior parte degli scenari di produzione, è consigliabile usare la modalità OffThread predefinita. Offre la massima velocità di risposta e consente al flusso di lavoro di continuare l'elaborazione mentre il consumer gestisce gli eventi.
Usare Lockstep quando il comportamento deterministico è più importante delle prestazioni, ad esempio negli unit test o nelle sessioni di debug.
// 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);
Esecuzione non in streaming
Entrambe le modalità di esecuzione supportano l'esecuzione non in streaming tramite RunAsync. In modalità non di streaming, il flusso di lavoro viene eseguito fino al completamento e raccoglie tutti gli eventi in un Run oggetto anziché trasmetterli in modo incrementale:
Run run = await InProcessExecution.RunAsync(workflow, input);
// Access all emitted events
foreach (WorkflowEvent evt in run.OutgoingEvents)
{
// Process events
}
Poiché l'esecuzione non in streaming raccoglie tutti gli eventi dopo il completamento, il vantaggio di recapito degli eventi in tempo reale di OffThread non si applica. La differenza principale tra le modalità negli scenari non di streaming è il threading: OffThread esegue i superstep in un thread in background, liberando il thread chiamante mentre attende il completamento, mentre Lockstep esegue i superstep sul thread del chiamante, bloccandolo fino al termine del flusso di lavoro.
L'esecuzione non in streaming usa la modalità OffThread predefinita. Per usare Lockstep con esecuzione non di streaming:
Run run = await InProcessExecution.Lockstep.RunAsync(workflow, input);
Passaggi successivi
Le modalità di esecuzione non sono applicabili ai flussi di lavoro Python. I flussi di lavoro Python usano un singolo modello di esecuzione che gestisce l'elaborazione dei superstep e la consegna degli eventi tramite un generatore asincrono. Questo modello è simile alla modalità Lockstep .NET. I passaggi non avanzano a meno che il consumer non esegua attivamente il pull degli eventi dal generatore.
Per informazioni sull'esecuzione di flussi di lavoro Python, vedere Generatore flussi di lavoro ed esecuzione.
Quando si esegue un flusso di lavoro in Go, l'ambiente di esecuzione controlla la modalità di elaborazione dei superstep e il modo in cui gli eventi vengono recapitati al consumer. Il workflow/inproc pacchetto espone tre ambienti: Default/OffThread, Lockstepe .Concurrent
Overview
| OffThread / Predefinito | Lockstep | Concomitante | |
|---|---|---|---|
| Esecuzione dei superstep | Goroutine in background | Controllata dal consumer degli eventi | Goroutine in background |
| Recapito di eventi | Immediata, quando vengono generati gli eventi | In batch durante l'utilizzo dello stream | Immediata, quando vengono generati gli eventi |
| Migliore per | Streaming in tempo reale, scenari di produzione | Test, correzione di errori, ordinamento deterministico | Istanze di workflow condivise con associazioni sicure per l'accesso simultaneo |
OffThread
OffThread è la modalità di esecuzione predefinita. Questi sono equivalenti:
stream, err := inproc.Default.RunStreaming(ctx, wf, input)
stream, err := inproc.OffThread.RunStreaming(ctx, wf, input)
Come funziona
- Una goroutine in background esegue i superstep mentre sono presenti messaggi in sospeso.
- Man mano che gli esecutori generano output o eventi, gli eventi del flusso di lavoro vengono scritti nello stream.
- Il consumer legge gli eventi con
WatchStream, ricevendoli man mano che vengono prodotti. - Quando tutti i superstep sono completati e non rimane alcun messaggio, l'esecuzione si arresta con stato inattivo o richiesta in sospeso.
Esecuzioni simultanee
Usare inproc.Concurrent quando tutte le associazioni dell'executor nel flusso di lavoro supportano l'esecuzione condivisa simultanea:
stream, err := inproc.Concurrent.RunStreaming(ctx, wf, input)
if err != nil {
return err
}
defer stream.Close(ctx)
Lockstep
In modalità Lockstep, l'esecuzione del workflow procede man mano che il consumer legge dallo stream. Ciò rende deterministico l'ordinamento degli eventi per i test e il debug.
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
}
Come funziona
- Il consumer chiama
WatchStream, che avvia il ciclo di esecuzione. - Un superstep viene eseguito fino al completamento e gli eventi vengono accumulati.
- Gli eventi accumulati vengono passati al consumatore.
- Il superstep successivo inizia solo dopo che il consumer riceve gli eventi del superstep precedente.
Quando usare Lockstep
Usare Lockstep quando il comportamento deterministico conta più del flusso a bassa latenza, ad esempio unit test, debug o scenari in cui si vogliono elaborare completamente gli eventi di un superstep prima dell'inizio del passaggio successivo.
Scelta di una modalità di esecuzione
Per la maggior parte degli scenari di produzione, usare inproc.Default o inproc.OffThread. Usare inproc.Lockstep quando l'ordinamento di eventi deterministici è più importante della latenza di streaming, ad esempio nei test. Usare inproc.Concurrent solo quando ogni associazione nel flusso di lavoro supporta l'esecuzione condivisa simultanea.
// 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)
Esecuzione non in streaming
Tutti gli ambienti di esecuzione supportano anche la modalità non in streaming Run, che viene eseguita fino al successivo arresto e memorizza gli eventi emessi nell'esecuzione restituita.
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)
}
}