Production hardening: fix duplicate-run race, scale cliffs, crash/leak/error-path bugs - #5
Merged
Merged
Conversation
Closes the check-then-insert race where two concurrent starts (manual + scheduler, or double-click) could both create an active run and double-process the whole table. A partial unique index is the atomic backstop; StartRun maps the conflict to ErrTaskBusy.
Missing run/task now 404; duplicate task name and start-while-active now 409 instead of a 500 that leaked the Postgres constraint.
Cap MaxOpenConns/idle/lifetime so a fleet can't exhaust the target's connections and stale conns are recycled on long runs; add per-batch and count-query timeouts so a hung query can't pin a run in 'running' forever. Also drop the per-batch runs.Get in solo mode (in-memory counters).
PlanLeases caps at MaxLeases and widens the stride for huge/sparse key spaces (e.g. snowflake ids to 10^18), and is safe near MaxInt64 — no more OOM or infinite loop. Enqueue ships leases in chunks.
A persistently failing target now fails the run via a stall detector (no progress + climbing lease failures) instead of churning forever. Heartbeats run on a background ticker so a slow/throttled batch can't be falsely reaped. Runner/worker goroutines recover from panics so one bad run can't crash the process.
…ess/failure A 2xx with an empty or malformed body no longer either fails the whole run or silently marks every row affected — the batch's rows are quarantined for retry so the operator sees the contract violation.
…rage gap Reap dead websocket subscribers (abrupt tab close no longer leaks). Anchor the /app auth bypass to a path boundary. Emit a coverage_gap event when a run walks fewer rows than counted (NULLable cursor).
Live console reconnects with backoff (shows Reconnecting… instead of silently freezing), clears the slider debounce on unmount, and guards an invalid run id.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Production-readiness audit + fixes
Acting as SDET: I set up a sandbox, tested it like a real user at scale (millions/billions of rows), ran adversarial code audits of the concurrency / scale / error-path subsystems, and fixed everything through Medium severity in this PR. Every fix has a test or a live-reproduced before/after.
🔴 Critical
ActiveForTask→INSERTwasn't atomic and had no DB constraint — I reproduced 2 active runs from 10 concurrent starts, i.e. two runners backfilling the same table at once. Fixed with a partial unique index (runs_one_active_per_task); StartRun maps the conflict to a clean 409. New test fires 12 concurrent creates → exactly 1 wins.🟠 High
MaxInt64).PlanLeasesis now capped atMaxLeases, stride-widening, and overflow-safe;Enqueueships in chunks. Unit-tested with 10^12 span andMaxInt64edges.runningforever on a persistently failing target. Added a stall detector (no progress + climbing lease failures) — live test: a failing fleet run now fails in ~20s instead of hanging.recover()and fail just that run.coverage_gapevent. (Non-unique cursors are actually safe — verified.)🟡 Medium
GET /runs/{missing}andPOST /tasks/{missing}/runsnow 404 (were 500)./appauth bypass anchored to a path boundary (/apple,/app/../tasksno longer skip auth).RetryQuarantinehardcoded the pgx driver → broke MySQL quarantine retry. Now dialect-aware.🟢 Efficiency (billion-row scale)
runs.Getin solo mode (in-memory counters) — halves control-store reads on long runs.Verified
OneActiveRunPerTask(12-way race),PlanLeasesBounded,PlanLeasesOverflowSafe,ActiveRunFreesOnTerminal.Deliberately deferred (documented, low-risk)
checkpointsgrowth (1 row/batch) — a retention/prune job is a separate follow-up.