1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
//! Static configuration for the native `WorkflowService`: the canonical entity
//! name, the eight per-transition outbox topics, the stored status tokens, the
//! master-plan 9.12 bounds, and the once-resolved step-timeout / tick-batch knobs
//! (no per-request/per-tick env reads).
use OnceLock;
pub const WORKFLOW_MSG: &str = "udb.core.workflow.entity.v1.WorkflowInstance";
// ── outbox topics (one per state transition) ───────────────────────────────────
pub const TOPIC_STARTED: &str = "udb.workflow.started.v1";
pub const TOPIC_STEP_ADVANCED: &str = "udb.workflow.step.advanced.v1";
pub const TOPIC_COMPLETED: &str = "udb.workflow.completed.v1";
pub const TOPIC_SIGNALED: &str = "udb.workflow.signaled.v1";
pub const TOPIC_CANCELLED: &str = "udb.workflow.cancelled.v1";
pub const TOPIC_COMPENSATE_STEP: &str = "udb.workflow.compensate.step.v1";
pub const TOPIC_COMPENSATED: &str = "udb.workflow.compensated.v1";
pub const TOPIC_FAILED: &str = "udb.workflow.failed.v1";
// ── stored status tokens (VARCHAR, short form) ─────────────────────────────────
// RUNNING/COMPLETED are written as SQL literals in the tick's forward UPDATEs;
// the cancel-path and tick-writeback targets are named constants.
pub const STATUS_COMPENSATING: &str = "COMPENSATING";
pub const STATUS_CANCELLED: &str = "CANCELLED";
pub const STATUS_COMPENSATED: &str = "COMPENSATED";
pub const STATUS_FAILED: &str = "FAILED";
/// Upper bound on forward steps per workflow (master-plan 9.12: ≤20 steps). A
/// request beyond this is clamped down rather than rejected.
pub const MAX_WORKFLOW_STEPS: i32 = 20;
/// Upper bound on the opaque payload (master-plan 9.12: ≤8 KiB). Bounds the durable
/// row and the fired event so one workflow cannot bloat the outbox.
pub const MAX_PAYLOAD_BYTES: usize = 8 * 1024;
/// Same bound on the compensation list handed to the saga engine.
pub const MAX_COMPENSATIONS_BYTES: usize = 8 * 1024;
/// Default upper bound (seconds) a RUNNING instance may sit without a state
/// transition before the tick's timeout sweep (16.3.4) fails it. Overridable via
/// `UDB_WORKFLOW_STEP_TIMEOUT_SECS`, resolved ONCE through
/// [`workflow_step_timeout_secs`] — never a per-tick env read.
pub const WORKFLOW_STEP_TIMEOUT_SECS: i64 = 3600;
/// Payload key stamping how many `compensate.step` events have already been
/// emitted for a COMPENSATING instance, so a re-tick never re-emits (16.3.2
/// exactly-once guard; belt-and-braces on top of the atomic emit+transition).
pub const COMPENSATE_EMITTED_KEY: &str = "compensate_emitted_steps";
/// Resolve the step timeout exactly once (no per-tick env reads).
pub
/// Default batch the tick advances per pass — a named constant (no per-request env
/// reads). Bounds how many DUE instances one tick advances so a backlog can't
/// starve the transaction. Referenced by the serve() leader-spawn block (follow-up).
pub const WORKFLOW_TICK_BATCH: i64 = 200;