pub struct TimerEntry {
pub workflow_id: WorkflowId,
pub timer_id: TimerId,
pub fire_at: DateTime<Utc>,
pub armed_seq: u64,
}Expand description
Durable timer record returned by crate::ReadableEventStore::expired_timers.
Fields§
§workflow_id: WorkflowIdWorkflow that owns the timer.
timer_id: TimerIdTimer identifier within the owning workflow.
fire_at: DateTime<Utc>Instant at which the timer is due to fire.
armed_seq: u64The workflow-history sequence of the TimerStarted event that armed
this row, or 0 for an arming that records no TimerStarted (the
schedule coordinator’s trigger timers — sequence numbers start at 1,
so 0 can never collide with a recorded arming).
This is the row-identity component that makes value-conditional
retirement discriminate a RE-ARM TO THE IDENTICAL INSTANT: without it,
a named timer re-armed to the same fire_at encodes byte-identically
to the consumed arming, so a stale retirement deletes the live
replacement’s row — and a past-due replacement is never re-armed by
the boot sweep (which only restores future armings), a permanently
lost wake. Every re-arm records a new TimerStarted with a strictly
higher sequence, so (fire_at, armed_seq) is unique per arming. The
store treats the value as an opaque identity component: it never
orders or interprets it.
serde(default): a pre-0.25 store’s rows carry no armed_seq, and a
decoder that refuses them bricks the boot of every upgraded server —
the 2026-08-26 v0.25.0 upgrade failure, hit on the first real store
this release met. 0 is the documented no-recorded-arming value, so a
legacy row decodes to a valid identity. A legacy row’s BYTES still
predate this field, so value-conditional retirement must also accept
the legacy encoding; the store backends own that half.
Trait Implementations§
Source§impl Clone for TimerEntry
impl Clone for TimerEntry
Source§fn clone(&self) -> TimerEntry
fn clone(&self) -> TimerEntry
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more