Defining Steps
Usestep.run() to define a step within a workflow:
retryPolicy). The second argument is the async function to execute. The
function’s return value is stored and returned on subsequent replays.
Why Steps Matter
Consider a workflow that charges a credit card and sends an email:- The workflow restarts from the beginning
- The “charge-card” step sees it already completed and returns instantly
- The “send-email” step runs normally
Step Names
Step names identify checkpoints during replay and should be stable across code changes. Use descriptive names that reflect what the step does::1, :2, and so on in
encounter order. This is most useful for dynamic steps
where the number of steps isn’t known ahead of time.
Return Values
Steps can return any JSON-serializable value:Step results must be JSON-serializable. Avoid returning functions, circular
references, or class instances with methods.
Step Types
OpenWorkflow provides five step types:step.run()
Executes arbitrary async code and memoizes the result:
step.sleep()
Pauses the workflow until a specified duration has elapsed. See
Sleeping for details:
step.runWorkflow()
Starts a child workflow and waits for its result durably:
step.sendSignal()
Sends a signal to all workflows currently waiting on that signal name:
step.waitForSignal()
Pauses the workflow until a matching signal is sent, or the timeout expires:
Retry Policy (Optional)
Control backoff and retry limits for an individual step:retryPolicy fields you omit fall back to defaults. Step retry policies
are independent from the workflow-level retry policy. See
Retries for the full behavior and defaults.
Error Handling
If a step throws an error, the error is recorded and the workflow fails:What Makes a Good Step
Each step should be a meaningful unit of work. Good steps:- Represent a single logical operation (fetch user, send email, charge card)
- Have side effects that shouldn’t be repeated (payments, notifications)
- Take a reasonable amount of time (not too granular, not too coarse)