Communication
Turbine has two durable communication mechanisms: Send/Recv for direct messaging and Events for key-value signaling.
Send / Recv
Point-to-point messaging between workflows.
go
// In workflow A: send a message to workflow B
turbine.Send(ctx, targetWorkflowID, "payload", "my-topic")
// In workflow B: receive (blocks until message arrives or timeout)
msg, err := turbine.Recv[string](ctx, "my-topic", 30*time.Second)If the timeout expires before a message arrives, Recv returns the zero value.
Messages are recorded as durable steps, on recovery, if the message was already received, the saved result is replayed.
Sending from HTTP Handlers
Outside a workflow, use rt.SendToWorkflow() or create a context with rt.NewContext():
go
// Option 1: SendToWorkflow (convenience)
err := rt.SendToWorkflow(workflowID, "payload", "my-topic")
// Option 2: NewContext + Send
tCtx := rt.NewContext(re.Request.Context())
err := turbine.Send(tCtx, workflowID, "payload", "my-topic")See Context for more on using Turbine APIs from handlers.
Events
Key-value signaling scoped to a workflow. GetValue blocks until the key is set or the timeout expires.
go
// In workflow A: set a key-value event
turbine.SetValue(ctx, "status", "ready")
// In workflow B: get the event (blocks until set or timeout)
val, err := turbine.GetValue[string](ctx, workflowID, "status", 10*time.Second)When to Use Which
| Send/Recv | Events | |
|---|---|---|
| Pattern | Point-to-point messaging | Publish/observe |
| Blocking | Receiver blocks until message or timeout | Reader blocks until key is set or timeout |
| Direction | Sender must know the target workflow ID | Reader must know the target workflow ID |
| Multiplicity | One message consumed by one receiver | Value readable by many observers |
| Use case | Approval decisions, task delegation | Status reporting, coordination flags |
See the events example for a working demo.