Kaizen
Browse modulesLifecyclelifecycle/serverFunctions

Function: drain()

function drain(options: DrainOptions): Promise<DrainResult>;

Defined in: server/lifecycle/dispatcher.ts:82

Drain a batch of pending effects from the transactional outbox.

Per call:

  1. Claim a batch (pending OR expired-lease rows → processing, stamping claimedBy/lockedUntil and INCREMENTING attempts AT CLAIM TIME so a handler crash still counts toward the dead-letter threshold). Poison rows already at maxAttempts are dead-lettered (failed) and not returned.
  2. Run handler per claimed row, in (transitionId, ordinal) order.
  3. Success → dispatched + release lease. Failure → pending (retry) or failed (dead-letter) once attempts >= maxAttempts, releasing the lease.

Ordering is best-effort: one drain invokes its claimed rows sequentially in (transitionId, ordinal) order. Effects are independent units of work; a failure does not block later ordinals, and concurrent drain calls can overlap. Do not model a multi-step workflow as several ordered effects.

The claim runs in its own short transaction; handlers run OUTSIDE it (so a slow handler doesn't hold a DB transaction open). Each outcome write is isolated: a DB error on one row's bookkeeping is logged and the drain continues (the row's lease will expire and be reclaimed). Call repeatedly (cron / worker loop) until claimed === 0.

Must be called outside an ambient transaction. Otherwise the claim joins the caller's transaction and a later rollback can undo the claim after the external handler has already run.

Parameters

ParameterType
optionsDrainOptions

Returns

Promise<DrainResult>

On this page