keiro
Safe HaskellNone
LanguageGHC2024

Keiro.Workflow.Awakeable.Schema

Description

The keiro_awakeables table: durable storage for awakeables (external promises a workflow suspends on).

Mirrors the Keiro.Timer / Keiro.Timer.Schema split: this module owns the row type, the AwakeableStatus lifecycle, and the hasql statements; Keiro.Workflow.Awakeable owns the effectful authoring/completion surface.

Callers normally use the re-exports / surface from Keiro.Workflow.Awakeable rather than this module directly; EP-44 imports countPendingAwakeables here without pulling in the effect surface.

Synopsis

Rows and status

data AwakeableStatus Source #

An awakeable's lifecycle state.

  • Pending — allocated and waiting for an external signal; the workflow is suspended on it.
  • Completed — signalled with a payload; terminal.
  • Cancelled — abandoned before it was signalled; terminal; also the decode fallback for an unrecognized stored value (the same defensive choice Keiro.Timer.Schema makes).

Constructors

Pending 
Completed 
Cancelled 

Instances

Instances details
Generic AwakeableStatus Source # 
Instance details

Defined in Keiro.Workflow.Awakeable.Schema

Associated Types

type Rep AwakeableStatus 
Instance details

Defined in Keiro.Workflow.Awakeable.Schema

type Rep AwakeableStatus = D1 ('MetaData "AwakeableStatus" "Keiro.Workflow.Awakeable.Schema" "keiro-0.12.0.0-inplace" 'False) (C1 ('MetaCons "Pending" 'PrefixI 'False) (U1 :: Type -> Type) :+: (C1 ('MetaCons "Completed" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Cancelled" 'PrefixI 'False) (U1 :: Type -> Type)))
Show AwakeableStatus Source # 
Instance details

Defined in Keiro.Workflow.Awakeable.Schema

Eq AwakeableStatus Source # 
Instance details

Defined in Keiro.Workflow.Awakeable.Schema

type Rep AwakeableStatus Source # 
Instance details

Defined in Keiro.Workflow.Awakeable.Schema

type Rep AwakeableStatus = D1 ('MetaData "AwakeableStatus" "Keiro.Workflow.Awakeable.Schema" "keiro-0.12.0.0-inplace" 'False) (C1 ('MetaCons "Pending" 'PrefixI 'False) (U1 :: Type -> Type) :+: (C1 ('MetaCons "Completed" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Cancelled" 'PrefixI 'False) (U1 :: Type -> Type)))

data AwakeableRow Source #

An awakeable row as stored: the deterministic id, the owning workflow's name and instance id, the live status, the signalled payload (JSON, set only once Completed), and the timestamps.

Instances

Instances details
Generic AwakeableRow Source # 
Instance details

Defined in Keiro.Workflow.Awakeable.Schema

Associated Types

type Rep AwakeableRow 
Instance details

Defined in Keiro.Workflow.Awakeable.Schema

Show AwakeableRow Source # 
Instance details

Defined in Keiro.Workflow.Awakeable.Schema

Eq AwakeableRow Source # 
Instance details

Defined in Keiro.Workflow.Awakeable.Schema

type Rep AwakeableRow Source # 
Instance details

Defined in Keiro.Workflow.Awakeable.Schema

Storage (run inside the caller's transaction)

registerAwakeableTx :: UUID -> Text -> Text -> Transaction () Source #

Insert a pending awakeable row inside the caller's transaction. Idempotent by ON CONFLICT (awakeable_id) DO NOTHING — exactly what EP-38's "arm must be idempotent" contract needs, since a resumed workflow re-runs the arming action on every resume until the awakeable resolves.

completeAwakeableTx :: UUID -> Value -> UTCTime -> Transaction Bool Source #

Transition a pending awakeable to completed, storing payload and the completion time, inside the caller's transaction. The status = pending guard makes a double-signal a no-op; returns True only when this call performed the transition (so the caller knows whether it was the one that resolved the promise).

cancelAwakeableTx :: UUID -> Transaction (Maybe (Text, Text)) Source #

Transition a pending awakeable to cancelled inside the caller's transaction, returning the owning workflow's (name, id) when this call performed the transition. Only pending rows match, so an already-completed (or already-cancelled) awakeable is left untouched and the call returns Nothing.

The owner coordinates are returned because cancellation writes no journal entry — there is no result value to record — so it is the only wake-source lifecycle transition that would otherwise leave the owning workflow's keiro_workflows row untouched. The caller flips that row in the same transaction (see Keiro.Workflow.Awakeable.cancelAwakeable) so discovery still surfaces the workflow.

lookupAwakeableStatusTx :: UUID -> Transaction (Maybe AwakeableStatus) Source #

Read an awakeable's current status inside the caller's transaction. Used after a guarded completion loses a row race, so the caller can distinguish a winning cancel (no journal append) from a winning signal (idempotent repair).

Read-only lookups

lookupAwakeable :: forall (es :: [Effect]). Store :> es => UUID -> Eff es (Maybe AwakeableRow) Source #

Read an awakeable row by id. Nothing if no such awakeable exists.

countPendingAwakeables :: forall (es :: [Effect]). Store :> es => Eff es Int Source #

Count awakeables currently pending. Read-only. EP-44 backs the keiro.workflow.awakeables.pending gauge with this.