Persistent Sleep
Persistent or durable sleep means the workflow's state is saved, and execution will resume after the duration has elapsed, even if the Obelisk server restarts.
The Runtime Support API contains method
sleep which creates an one-off
Join Set and blocks the execution
until the delay has timed out.
If the durable sleep is cancelled, sleep returns an error that must be handled by the workflow.
See Cancellation for
how delay cancellation fits into structured concurrency:
workflow_support::sleep(ScheduleAt::In(SchedulingDuration::Seconds(10)), None)
.map_err(|()| MyWorkflowError::Cancelled)?;
The trailing None names the one-off join set (a name is optional).
Another way to submit a persistent delay is to use
Heterogenous Join Set
with the submit_delay function.
fn two_delays_in_same_join_set() -> Result<(), ()> {
let join_set = workflow_support::join_set_create();
let _long = submit_delay(&join_set, ScheduleAt::In(DurationEnum::Seconds(10)));
let short = submit_delay(&join_set, ScheduleAt::In(DurationEnum::Milliseconds(10)));
// child executions can be added to this join set using `-submit` extension.
// `join_next` returns the completed value directly:
// `result<result<option<string>, option<string>>, join-next-error>`.
let res = join_next(&join_set)
.expect("submitted two delays, joining first, thus `join-next-error::all-processed` cannot happen");
assert!(res.is_ok()); // Ok(None) for an expired delay
// Read which response was processed from `join_set.last_id()`.
let Some(ResponseId::DelayId(first)) = join_set.last_id() else {
unreachable!("only delays have been submitted");
};
assert_eq!(short.id, first.id);
// long delay will be cancelled when the join set is closed.
Ok(())