Timer
View as MarkdownA Timer is a durable wait until a point in time. Dex Server keeps it. A Step returns it from WaitFor, and Execute runs when it fires. While the Step waits, no Worker holds memory, a thread, or a connection for it.
When to use a Timer
Use a Timer for a delay, a reminder, or a deadline. Combine it with another condition to build a timeout. For example, a Step that waits for either a Channel message or a Timer proceeds with whichever comes first. In Execute, the Step checks whether its Timer fired.
Guarantees
The server stores the Timer with the Flow. It survives Worker restarts and server failover.
Wait for a Timer
This Step waits for the number of seconds in its input:
class TimerExampleStep(Step[int]):
def wait_for(self, _context: Context, input: int) -> Wait:
return Wait.until(Timer.by_duration(timedelta(seconds=input)))
def execute(self, context: Context, _input: int) -> StepDecision:
print(context.has_timer_fired())
return graceful_complete("timer-fired")
Example: examples/python/dex_examples/primitives/timer/timer_flow.py
Skip a Timer
A Client can skip a Timer with SkipTimer. It selects the Timer by Flow ID, Step execution ID, and either the Timer's condition ID or the index of its condition in WaitFor. A skipped Timer acts as if it had fired. Use it in tests, or in production to run a waiting Step early. See Skip a Timer.
In this test of the order-processing example, the Ship Step waits on a Timer, and the test skips it:
await client.skip_timer(
flow_id,
SHIP_STEP,
TimerId.by_condition_index(0),
)
Example: examples/python/tests/integ/test_order_processing.py
See Step for how a Step combines conditions in WaitFor.
Reference
The Timer page of each SDK reference lists the API names in that language.
- Waits and Condition results cover how a Timer combines with other conditions and how a Step reads which one fired.
- Skip a Timer covers the Client call.