Skip to main content

Signals

View Markdown

A signal is a message delivered to a running flow by name. It is how a human approval, a webhook, or another service reaches a flow that is parked waiting for it.

Sending, from anywhere with a handle:

handle.signal("approval", Approval(approved = true, by = "abiola"))

Receiving, inside the flow body:

val approvals = flow.signals<Approval>("approval")
val approval = approvals.receive(30.minutes) // null if nothing arrives in time

Properties

  • Buffered from the start. Signals that arrive before the body asks for them are kept, so a flow can ask late. signals.available says how many are waiting, usable inside awaitUntil.
  • Ordered by arrival.
  • Durable. The signal is recorded in the run's history. A worker that restarts replays it.
  • Closed runs refuse signals. Sending to a finished run is an error, not a silent drop.

The parked run

While a flow waits on receive, nothing is running anywhere: no poller, no cron, no row in a table. The orchestrator holds the state and wakes the body when the signal lands, whether that is in a second or in a week. That is the cheapest possible way to wait for a person.

Remember: a signal is data, not a command. The body decides what it means.