Skip to main content

ff_backend_sqlite/queries/
suspend.rs

1//! SQL statements for suspend + claim_resumed_execution ops
2//! (RFC-023 Phase 2b.2.1).
3//!
4//! Mirrors `ff-backend-postgres/src/suspend_ops.rs` statement-by-
5//! statement with SQLite-dialect adjustments (`jsonb → TEXT`,
6//! `$n → ?n`, `FOR UPDATE` elided under single-writer `BEGIN IMMEDIATE`).
7
8// ── Dedup replay cache (ff_suspend_dedup) ─────────────────────────────
9
10pub const SELECT_SUSPEND_DEDUP_SQL: &str = "SELECT outcome_json FROM ff_suspend_dedup \
11     WHERE partition_key = ?1 AND idempotency_key = ?2";
12
13pub const INSERT_SUSPEND_DEDUP_SQL: &str = "INSERT INTO ff_suspend_dedup \
14     (partition_key, idempotency_key, outcome_json, created_at_ms) \
15     VALUES (?1, ?2, ?3, ?4) \
16     ON CONFLICT DO NOTHING";
17
18// ── Fence + attempt-index resolution ──────────────────────────────────
19
20pub const SELECT_ATTEMPT_EPOCH_SQL: &str =
21    "SELECT lease_epoch FROM ff_attempt \
22      WHERE partition_key = ?1 AND execution_id = ?2 AND attempt_index = ?3";
23
24pub const SELECT_EXEC_ATTEMPT_INDEX_SQL: &str =
25    "SELECT attempt_index FROM ff_exec_core \
26      WHERE partition_key = ?1 AND execution_id = ?2";
27
28// ── ff_suspension_current row ─────────────────────────────────────────
29
30/// Binds: 1=partition, 2=execution_id, 3=suspension_id,
31///        4=suspended_at_ms, 5=timeout_at_ms, 6=reason_code,
32///        7=condition_json, 8=timeout_behavior.
33pub const UPSERT_SUSPENSION_CURRENT_SQL: &str = "INSERT INTO ff_suspension_current \
34     (partition_key, execution_id, suspension_id, suspended_at_ms, \
35      timeout_at_ms, reason_code, condition, satisfied_set, member_map, \
36      timeout_behavior) \
37     VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, '[]', '{}', ?8) \
38     ON CONFLICT (partition_key, execution_id) DO UPDATE SET \
39       suspension_id = excluded.suspension_id, \
40       suspended_at_ms = excluded.suspended_at_ms, \
41       timeout_at_ms = excluded.timeout_at_ms, \
42       reason_code = excluded.reason_code, \
43       condition = excluded.condition, \
44       satisfied_set = '[]', \
45       member_map = '{}', \
46       timeout_behavior = excluded.timeout_behavior";
47
48pub const SELECT_SUSPENSION_CONDITION_AND_MAP_SQL: &str =
49    "SELECT condition, member_map FROM ff_suspension_current \
50      WHERE partition_key = ?1 AND execution_id = ?2";
51
52pub const UPDATE_SUSPENSION_MEMBER_MAP_SQL: &str =
53    "UPDATE ff_suspension_current SET member_map = ?1 \
54      WHERE partition_key = ?2 AND execution_id = ?3";
55
56// ── exec_core + attempt transitions ───────────────────────────────────
57
58pub const UPDATE_EXEC_CORE_SUSPEND_SQL: &str = "UPDATE ff_exec_core \
59     SET lifecycle_phase = 'suspended', \
60         ownership_state = 'released', \
61         eligibility_state = 'not_applicable', \
62         public_state = 'suspended', \
63         attempt_state = 'attempt_interrupted' \
64     WHERE partition_key = ?1 AND execution_id = ?2";
65
66pub const UPDATE_EXEC_CORE_RESUMABLE_SQL: &str = "UPDATE ff_exec_core \
67     SET public_state = 'resumable', \
68         lifecycle_phase = 'runnable', \
69         eligibility_state = 'eligible_now' \
70     WHERE partition_key = ?1 AND execution_id = ?2";
71
72// #356: `started_at_ms` is set-once on ff_exec_core via migration
73// 0016; the resume-claim path preserves the original first-claim
74// timestamp via COALESCE (seeds `?3 = now` as a defensible fallback
75// for any pre-0016-backfill exec that resumes before a first-claim
76// column-write — structurally the same as the PG sibling in
77// `ff-backend-postgres/src/suspend_ops.rs`).
78pub const UPDATE_EXEC_CORE_RUNNING_SQL: &str = "UPDATE ff_exec_core \
79     SET lifecycle_phase = 'active', ownership_state = 'leased', \
80         eligibility_state = 'not_applicable', \
81         public_state = 'running', attempt_state = 'running_attempt', \
82         started_at_ms = COALESCE(started_at_ms, ?3) \
83     WHERE partition_key = ?1 AND execution_id = ?2";
84
85pub const SELECT_EXEC_STATE_FOR_RESUME_SQL: &str =
86    "SELECT public_state, attempt_index FROM ff_exec_core \
87      WHERE partition_key = ?1 AND execution_id = ?2";
88
89pub const UPDATE_ATTEMPT_SUSPEND_SQL: &str = "UPDATE ff_attempt \
90     SET worker_id = NULL, \
91         worker_instance_id = NULL, \
92         lease_expires_at_ms = NULL, \
93         lease_epoch = lease_epoch + 1, \
94         outcome = 'attempt_interrupted' \
95     WHERE partition_key = ?1 AND execution_id = ?2 AND attempt_index = ?3";
96
97pub const UPDATE_ATTEMPT_CLAIM_RESUMED_SQL: &str = "UPDATE ff_attempt \
98     SET worker_id = ?1, worker_instance_id = ?2, \
99         lease_epoch = lease_epoch + 1, \
100         lease_expires_at_ms = ?3, started_at_ms = ?4, outcome = NULL \
101     WHERE partition_key = ?5 AND execution_id = ?6 AND attempt_index = ?7";
102
103pub const SELECT_ATTEMPT_LEASE_EPOCH_SQL: &str =
104    "SELECT lease_epoch FROM ff_attempt \
105      WHERE partition_key = ?1 AND execution_id = ?2 AND attempt_index = ?3";