.NET에서 워크플로를 실행할 때 실행 모드 는 슈퍼스텝이 처리되는 방법과 이벤트가 소비자에게 전달되는 방식을 제어합니다. 이 클래스는 InProcessExecution 두 가지 실행 모드인 OffThread 및 Lockstep을 노출합니다.
Overview
| OffThread(기본값) | Lockstep | |
|---|---|---|
| 슈퍼스텝 실행 | 백그라운드 스레드 | 소비자 스레드 |
| 이벤트 전달 | 이벤트가 발생함에 따라 즉시 실행 | 각 슈퍼스텝이 완료된 후 일괄 처리됨 |
| 단계 실행 | 이벤트 처리와 무관 | 일괄 처리된 이벤트가 소비될 때까지 일시 중지됨 |
| 동시성 | 슈퍼스텝이 실행되는 동안 사용자가 이벤트를 읽습니다. | 소비자와 슈퍼스텝 실행의 번갈아 수행 |
| 최적입니다 | 실시간 스트리밍, 프로덕션 시나리오 | 테스트, 디버깅, 결정적 순서 지정 |
OffThread
OffThread는 기본 실행 모드입니다. 슈퍼스텝은 백그라운드 스레드에서 실행되며, 이벤트는 채널 기반 구현을 통해 발생하자마자 실시간으로 스트리밍됩니다.
// 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);
작동 방식
- 백그라운드 작업은 메시지가 보류 중인 동안 지속적으로 상위 단계가 실행됩니다.
- 실행기가 출력 또는 이벤트를 생성할 때 결과
WorkflowEvent개체는 한정되지 않은Channel<WorkflowEvent>에 기록됩니다. - 소비자는 채널에서
WatchStreamAsync이벤트를 읽고, 생성되는 즉시 실시간으로 받습니다. - 모든 상위 단계가 완료되고 메시지가 남아 있지 않으면 실행이 중단되거나
IdlePendingRequests상태가 됩니다.
슈퍼스텝 루프와 소비자는 동시에 실행되므로 이벤트가 발생하는 즉시 나타나며 버퍼링 지연은 없습니다. 따라서 OffThread는 UI에 토큰별 업데이트 표시와 같이 대기 시간이 짧은 이벤트 배달이 중요한 스트리밍 시나리오에 이상적입니다.
동시 실행
또한 OffThread는 여러 실행에서 동일한 워크플로 인스턴스를 동시에 공유할 수 있는 동시 변형을 지원합니다.
await using StreamingRun run = await InProcessExecution.Concurrent.RunStreamingAsync(workflow, input);
Important
동시 실행을 수행하려면 워크플로의 모든 실행기를 생성자에서 선언 crossRunShareable 하거나 팩터리 메서드로 제공해야 합니다.
Lockstep
Lockstep 모드에서 슈퍼스텝은 백그라운드 작업이 아닌 소비자의 스레드 에서 실행됩니다. 이벤트는 각 슈퍼스텝 동안 누적되고 슈퍼스텝이 완료된 후 일괄 처리로 내보내집니다.
await using StreamingRun run = await InProcessExecution.Lockstep.RunStreamingAsync(workflow, input);
작동 방식
- 소비자는 실행 루프를 시작하는
WatchStreamAsync을 호출합니다. - 슈퍼스텝은 완료될 때까지 실행되며, 이벤트는 큐에 누적됩니다.
- 슈퍼스텝이 완료되면 대기 중인 모든 이벤트가 소비자에게 제공됩니다.
- 다음 슈퍼스텝은 소비자가 이전 이벤트로부터 모든 이벤트를 받은 후에만 시작됩니다.
번갈아 가는 패턴은 소비자와 워크플로 엔진이 한 번에 동시에 실행되지 않도록 합니다. 이벤트 배달은 결정적입니다. 슈퍼스텝의 모든 이벤트는 다음 슈퍼스텝의 이벤트 앞에 도착하도록 보장됩니다.
Lockstep을 사용하는 경우
Lockstep은 다음과 같은 경우에 유용합니다.
- 테스트 - 결정적 이벤트 순서 지정은 어설션을 간단하게 만듭니다.
- 디버깅 - 실행이 소비자의 스레드에 유지되는 경우 단계별 디버깅이 더 쉽습니다.
- 순서가 지정된 처리 - 다음 슈퍼스텝이 시작되기 전에 한 슈퍼스텝의 이벤트를 완전히 처리해야 하는 시나리오입니다.
실행 모드 선택
대부분의 프로덕션 시나리오에서는 기본 OffThread 모드를 사용하는 것이 좋습니다. 최상의 응답성을 제공하고 소비자가 이벤트를 처리하는 동안 워크플로가 처리를 계속할 수 있도록 합니다.
단위 테스트 또는 디버깅 세션과 같이 성능보다 결정적 동작이 더 중요한 경우 Lockstep 을 사용합니다.
// 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);
스트리밍이 아닌 실행
두 실행 모드 모두 RunAsync를 통한 비 스트리밍 실행을 지원합니다. 워크플로는 완료될 때까지 실행되어, 모든 이벤트를 Run 개체로 수집하며 비 스트리밍 모드에서는 증분 스트리밍하지 않습니다.
Run run = await InProcessExecution.RunAsync(workflow, input);
// Access all emitted events
foreach (WorkflowEvent evt in run.OutgoingEvents)
{
// Process events
}
비 스트리밍 실행은 완료 후 모든 이벤트를 수집하므로 OffThread의 실시간 이벤트 배달 혜택은 적용되지 않습니다. 비 스트리밍 시나리오의 모드 간 주요 차이점은 스레딩입니다. OffThread는 백그라운드 스레드에서 상위 스텝을 실행하여 완료를 기다리는 동안 호출 스레드를 해제하는 반면 Lockstep은 호출자의 스레드에서 상위 스텝을 실행하여 워크플로가 완료될 때까지 차단합니다.
비 스트리밍 실행은 기본 OffThread 모드를 사용합니다. 비 스트리밍 실행과 함께 Lockstep을 사용하려면 다음을 수행합니다.
Run run = await InProcessExecution.Lockstep.RunAsync(workflow, input);
다음 단계
실행 모드는 Python 워크플로에 적용되지 않습니다. Python 워크플로는 비동기 생성기를 통해 슈퍼스텝 처리 및 이벤트 배달을 처리하는 단일 실행 모델을 사용합니다. 이 모델은 .NET Lockstep 모드와 유사합니다. 소비자가 생성기에서 이벤트를 적극적으로 끌어온 경우가 아니면 단계가 진행되지 않습니다.
Python 워크플로 실행에 대한 자세한 내용은 워크플로 작성기 및 실행을 참조하세요.
Go에서 워크플로를 실행할 때 실행 환경은 슈퍼스텝이 처리되는 방법과 이벤트가 소비자에게 전달되는 방식을 제어합니다. 패키지는 workflow/inproc 세 가지 환경( , Default및 /)을 노출합니다OffThreadLockstepConcurrent.
Overview
| OffThread/Default | Lockstep | 일치하는 | |
|---|---|---|---|
| 슈퍼스텝 실행 | 배경 고루틴 | 이벤트 소비자에 의해 구동됨 | 배경 고루틴 |
| 이벤트 전달 | 이벤트가 발생함에 따라 즉시 실행 | 스트림이 소비되는 동안 일괄 처리됨 | 이벤트가 발생함에 따라 즉시 실행 |
| 최적입니다 | 실시간 스트리밍, 프로덕션 시나리오 | 테스트, 디버깅, 결정적 순서 지정 | 동시 안전 바인딩을 사용하는 공유 워크플로 인스턴스 |
OffThread
OffThread는 기본 실행 모드입니다. 이러한 항목은 동일합니다.
stream, err := inproc.Default.RunStreaming(ctx, wf, input)
stream, err := inproc.OffThread.RunStreaming(ctx, wf, input)
작동 방식
- 메시지가 대기 중인 동안 백그라운드 고루틴이 슈퍼스텝을 실행합니다.
- 실행기가 출력 또는 이벤트를 생성할 때 워크플로 이벤트는 스트림에 기록됩니다.
- 소비자는
WatchStream를 사용하여 이벤트를 읽고, 생성되는 대로 이를 수신합니다. - 모든 슈퍼스텝이 완료되고 메시지가 남아 있지 않으면 유휴 상태 또는 보류 중인 요청 상태로 실행이 중지됩니다.
동시 실행
워크플로의 모든 실행기 바인딩이 동시 공유 실행을 지원하는 경우에 사용합니다 inproc.Concurrent .
stream, err := inproc.Concurrent.RunStreaming(ctx, wf, input)
if err != nil {
return err
}
defer stream.Close(ctx)
Lockstep
Lockstep 모드에서는 소비자가 스트림에서 읽을 때 워크플로 실행이 진행됩니다. 이렇게 하면 테스트 및 디버깅에 대한 이벤트 순서가 결정적입니다.
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
}
작동 방식
- 소비자는 실행 루프를 시작하는
WatchStream을 호출합니다. - 슈퍼스텝은 완료될 때까지 실행되며 이벤트가 누적됩니다.
- 누적된 이벤트는 컨슈머에게 전달됩니다.
- 다음 슈퍼스텝은 소비자가 이전 슈퍼스텝의 이벤트를 수신한 후에만 시작됩니다.
Lockstep을 사용하는 경우
단위 테스트, 디버깅 또는 다음 슈퍼스텝이 시작되기 전에 한 슈퍼스텝의 이벤트를 완전히 처리하려는 시나리오와 같이 대기 시간이 짧은 스트리밍보다 결정적 동작이 중요한 경우 Lockstep을 사용합니다.
실행 모드 선택
대부분의 프로덕션 시나리오에서 사용 inproc.Default 하거나 inproc.OffThread. 테스트와 같이 스트리밍 대기 시간보다 결정적 이벤트 순서 지정이 더 중요한 경우에 사용합니다 inproc.Lockstep . 워크플로의 모든 바인딩이 동시 공유 실행을 지원하는 경우에만 사용합니다 inproc.Concurrent .
// 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)
스트리밍이 아닌 실행
또한 모든 실행 환경은 비 스트리밍을 Run지원합니다. 이 환경은 다음 중지될 때까지 실행되고 반환된 실행에 내보낸 이벤트를 저장합니다.
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)
}
}