ITimeoutStore
Overview
Section titled “Overview”ITimeoutStore is the persistence interface backing scheduled saga timeouts. When a process handler calls ctx.requestTimeout(...), the bus persists a TimeoutRecord here. A background poller calls claimDue on a fixed interval, claims any timeouts whose runAt has elapsed, dispatches them back into the saga, and deletes them.
Implementations must claim atomically: two pollers (or two hosts running the same bus) must never fire the same timeout twice.
Import
Section titled “Import”import type { ITimeoutStore, TimeoutRecord,} from '@serviceconnect/core';Signature
Section titled “Signature”export interface TimeoutRecord { readonly id: string; readonly name: string; readonly sagaCorrelationId: string; readonly sagaDataType: string; readonly runAt: Date; readonly payload?: Readonly<Record<string, unknown>>;}
export interface ITimeoutStore { schedule(record: Omit<TimeoutRecord, 'id'>): Promise<TimeoutRecord>; claimDue(now: Date, limit: number): Promise<readonly TimeoutRecord[]>; delete(id: string): Promise<void>;}Members
Section titled “Members”schedule(record)— persist a new timeout. The caller passes everything except the id; the store assigns one and returns the fullTimeoutRecord. Thepayloadfield is opaque — implementations should round-trip it unchanged so the saga handler sees whatever was passed torequestTimeout.claimDue(now, limit)— return up tolimittimeouts whoserunAt <= now. Implementations must atomically claim the rows they return (e.g. viafindAndUpdatewith aclaimedAtcolumn, a SELECT FOR UPDATE SKIP LOCKED in SQL, or an equivalent guard) so two pollers do not both fire the same timeout. Returning rows inrunAtorder is recommended but not required.delete(id)— remove a timeout. Called by the timeout poller after the timeout has been fired (published) successfully. The framework does not currently delete still-pending timeouts when a saga completes, so scheduled-but-unfired timeouts for a completed saga are not cleaned up automatically. Safe to no-op if the row no longer exists.