Repository navigation
fix: fence org lifecycle status and lease writes - #2317
Conversation
transitionRow runs a caller-built UPDATE guarded on the states the writer read and fails with TransitionConflictError when the row already moved.
Writers updated status columns by id alone, so one that read state earlier silently overwrote a concurrent transition. Every writer now guards its UPDATE on the state it decided from, through transitionRow. Error issues: applyTransition returns a 409 when it loses the race; the tick only regresses rows still done; alert and integration reopens land in regressed with the tick's bookkeeping. Investigations: late diagnoses on failed or resolved runs are dropped; manual status changes may only resolve a finished run or reopen it to its own verdict (MANUAL_INVESTIGATION_TRANSITIONS, 409 otherwise); restart refuses a running pass; one heartbeat-aware stale sweep; anomaly triage settles only once.
…iters The enqueue path's stale sweep now uses the shared heartbeat-aware sweep, markFailed is guarded on investigating, restart rescues a run whose start never claimed it, and the errors tick skips a wake or lease expiry that lost to a concurrent move (a renewed snooze included) instead of failing the org's tick. The investigation detail page disables resolve and restart on a run in flight, matching the server's rules.
…beat The lease clear is guarded on still being expired, and only an issue still in_progress drops to todo. The detail page lets an unclaimed run be run again, and a renewed snooze is covered by a test.
… caller's reservation
…tes and an active repo
…ismiss stamps resolvedAt
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 24 minutes. View limit details
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. |
This comment has been minimized.
This comment has been minimized.
Maple review🟢 Confidence 10/10 · safe to merge. Every fence and lease is pinned by a PGlite test at the state boundary it guards, and nothing outside those writes changed. Each lifecycle write now states the state it expects: schema apply fences on its run id, post-merge settle on its lease, reward finalize on its reservation, repo sync status on an active repo in the prior state. All paths are pinned by PGlite tests. The open
Before merge
Production impactOpen errors in the changed files (3)
After this merges, Maple checks whether they stop.
|
|
Merged with 1 step from "Before merge" still open. If it is done, tick it on the review comment; if not, now is the time.
|
Maple: after this shippedDeployed to New errors since the deploy:
Errors in the changed files:
Maple looks once, an hour after the first deploy that carries the merge. |
Stacked on #2310. Closes the remaining status and lease races outside alerts.
workflow_instance_idand passes it to the workflow. Every progress write, the schema-version stamp and the failure path are fenced on that id. A reclaimed instance stops before its next DDL and ends assupersededwithout touching the org's settings. Long statements heartbeat every 5 minutes, so a live backfill is never reclaimed as stale.settleis fenced onwaitingplus the examination's lease, likereportedalready was, so a stale tick cannot overwrite a report.reservereturns the reservation it took.finalizeandreleaseonly clear that one. A holder whose lease lapsed still records the claim but leaves the next holder's lease alone.active. A continuation or a stale error can no longer regress areadyrepo, and removed repos are not written.statusis branded with the literal schema (no migration;db:generatereports no change). Reconcile's status moves are guarded on the status it read. Concurrent inserts no longer collide.dismissnow stampsresolvedAt, like reconcile's resolve does.runningpast the rescan window asfailed.Rollout note: a schema-apply instance already running when this deploys has no run id. It fails on its payload, and the org can re-apply once the 30-minute stale window passes.
Tests (PGlite):
tsrs --noEmitis clean for packages/db, packages/domain, packages/backend and apps/api.oxlint -c .oxlintrc.effect.jsonis clean on the touched files.🤖 Generated with Claude Code
Open in [code]smith · Need help on this PR? Tag
@codesmith-botwith what you need.