2.3 KiB
2.3 KiB
title, impact, impactDescription, tags
| title | impact | impactDescription | tags |
|---|---|---|---|
| Use Streams for Real-Time Data | MEDIUM | Enables streaming results from long-running workflows | communication, stream, real-time, channel |
Use Streams for Real-Time Data
Workflows can stream data to clients in real-time using dbos.WriteStream, dbos.CloseStream, and dbos.ReadStream/dbos.ReadStreamAsync. Useful for LLM output streaming or progress reporting.
Incorrect (accumulating results then returning at end):
func processWorkflow(ctx dbos.DBOSContext, items []string) ([]string, error) {
var results []string
for _, item := range items {
result, _ := dbos.RunAsStep(ctx, func(ctx context.Context) (string, error) {
return processItem(item)
}, dbos.WithStepName("process"))
results = append(results, result)
}
return results, nil // Client must wait for entire workflow to complete
}
Correct (streaming results as they become available):
func processWorkflow(ctx dbos.DBOSContext, items []string) (string, error) {
for _, item := range items {
result, err := dbos.RunAsStep(ctx, func(ctx context.Context) (string, error) {
return processItem(item)
}, dbos.WithStepName("process"))
if err != nil {
return "", err
}
dbos.WriteStream(ctx, "results", result)
}
dbos.CloseStream(ctx, "results") // Signal completion
return "done", nil
}
// Read the stream synchronously (blocks until closed)
handle, _ := dbos.RunWorkflow(ctx, processWorkflow, items)
values, closed, err := dbos.ReadStreamstring, "results")
Async stream reading with channels:
ch, err := dbos.ReadStreamAsyncstring, "results")
if err != nil {
log.Fatal(err)
}
for sv := range ch {
if sv.Err != nil {
log.Fatal(sv.Err)
}
if sv.Closed {
break
}
fmt.Println("Received:", sv.Value)
}
Key behaviors:
- A workflow may have any number of streams, each identified by a unique key
- Streams are immutable and append-only
- Writes from workflows happen exactly-once
- Streams are automatically closed when the workflow terminates
ReadStreamblocks until the workflow is inactive or the stream is closedReadStreamAsyncreturns a channel ofStreamValue[R]for non-blocking reads
Reference: Workflow Streaming