fix: idempotent migrations (ADD COLUMN IF NOT EXISTS), stale doc, safety note
This commit is contained in:
parent
7d36ec5e1f
commit
c47faf0af9
5 changed files with 80 additions and 26 deletions
|
|
@ -162,23 +162,34 @@ pub struct Broker {
|
|||
/// `messages` — the last column added before versioning.
|
||||
const BROKER_MIGRATIONS: &[&str] = &[
|
||||
// v1: acked_at on messages, with backfill so existing delivered rows
|
||||
// are not phantom-requeued on the next open. The multi-statement
|
||||
// batch runs atomically (execute_batch wraps in a transaction).
|
||||
"ALTER TABLE messages ADD COLUMN acked_at INTEGER;\
|
||||
UPDATE messages SET acked_at = delivered_at WHERE delivered_at IS NOT NULL;",
|
||||
// are not phantom-requeued on the next open.
|
||||
//
|
||||
// IF NOT EXISTS: safe to run on a partially-migrated legacy DB where
|
||||
// acked_at already exists but priority (the legacy marker) does not.
|
||||
// The BEGIN/COMMIT block makes ALTER + UPDATE atomic — if the UPDATE
|
||||
// fails the version counter is not bumped and the whole step retries.
|
||||
"BEGIN;\
|
||||
ALTER TABLE messages ADD COLUMN IF NOT EXISTS acked_at INTEGER;\
|
||||
UPDATE messages SET acked_at = delivered_at \
|
||||
WHERE delivered_at IS NOT NULL AND acked_at IS NULL;\
|
||||
COMMIT;",
|
||||
// v2: in_reply_to for thread-parent tracking. NULL = root of a thread.
|
||||
"ALTER TABLE messages ADD COLUMN in_reply_to INTEGER",
|
||||
"ALTER TABLE messages ADD COLUMN IF NOT EXISTS in_reply_to INTEGER",
|
||||
// v3: priority for operator-message fast-path. Rebuild the delivery
|
||||
// index to include priority as a secondary sort key.
|
||||
"ALTER TABLE messages ADD COLUMN priority INTEGER NOT NULL DEFAULT 0;\
|
||||
"BEGIN;\
|
||||
ALTER TABLE messages ADD COLUMN IF NOT EXISTS \
|
||||
priority INTEGER NOT NULL DEFAULT 0;\
|
||||
DROP INDEX IF EXISTS idx_messages_undelivered;\
|
||||
CREATE INDEX idx_messages_undelivered \
|
||||
ON messages (recipient, priority DESC, id) WHERE delivered_at IS NULL",
|
||||
CREATE INDEX IF NOT EXISTS idx_messages_undelivered \
|
||||
ON messages (recipient, priority DESC, id) WHERE delivered_at IS NULL;\
|
||||
COMMIT;",
|
||||
// v4: attempt_count on reminders for the MAX_REMINDER_ATTEMPTS cap.
|
||||
"ALTER TABLE reminders ADD COLUMN attempt_count INTEGER NOT NULL DEFAULT 0",
|
||||
"ALTER TABLE reminders ADD COLUMN IF NOT EXISTS \
|
||||
attempt_count INTEGER NOT NULL DEFAULT 0",
|
||||
// v5: last_error on reminders — last delivery failure surfaced on the
|
||||
// dashboard so a stuck reminder is visible without digging in logs.
|
||||
"ALTER TABLE reminders ADD COLUMN last_error TEXT",
|
||||
"ALTER TABLE reminders ADD COLUMN IF NOT EXISTS last_error TEXT",
|
||||
];
|
||||
|
||||
impl Broker {
|
||||
|
|
@ -1134,11 +1145,6 @@ impl Broker {
|
|||
}
|
||||
}
|
||||
|
||||
/// Idempotent messages-table migrations. Adds `acked_at` and
|
||||
/// back-fills it for every already-delivered row, so the
|
||||
/// pre-migration sessions count as "fully handled" and won't be
|
||||
/// resurfaced by the first `requeue_inflight` after upgrade.
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
|
|||
Loading…
Reference in a new issue