Skip to content

migration-runner: extend advisory-lock guard to webhook-triggers, routines, workflow-deploy-source - #504

Merged
TheGreatAxios merged 3 commits into
cl-7211-migration-advisory-lockfrom
cl-7241-migration-advisory-lock-rollout
Aug 30, 2026
Merged

TheGreatAxios merged 3 commits into
cl-7211-migration-advisory-lockfrom
cl-7241-migration-advisory-lock-rollout

Conversation

@TheGreatAxios

@TheGreatAxios TheGreatAxios commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Stacked on migration-runner: shared advisory-lock guard for package migrations #480 (cl-7211-migration-advisory-lock), which introduced @corbits/migration-runner's applyPackageMigrations and converted six packages to it, fixing a check-then-act race in their migration ledgers.

  • Fixes CL-7241: @corbits/webhook-triggers, @corbits/routines, and @corbits/workflow-deploy-source had the identical racy shape — a SELECT-then-insert loop with no lock — outside CL-7211's scope. Converts all three to call applyPackageMigrations, exactly as the six were converted (keep the migrations array + type export, drop the bootstrap/lock/quoteIdentifier boilerplate, thin applyXMigrations wrapper). Every exported function's name and signature is unchanged, so scripts/db-setup.ts and other callers need no changes, and this is safe for databases with an already-populated ledger (no drops, no truncates, ledger schema unchanged).

  • Adds a "two replicas booting concurrently" test to all three packages' own test/migrations.test.ts (mirroring packages/migration-runner/test/migration-runner.test.ts's own concurrency test), each verified to fail against the pre-conversion racy code and pass after conversion. Note: none of the six packages CL-7211 converted got a package-level concurrency test of their own — they rely solely on the shared migration-runner package test covering the mechanics generically. Worth a look on migration-runner: shared advisory-lock guard for package migrations #480 since it's the same gap this PR was asked not to repeat; not fixed here since it's out of this PR's scope.

  • Computed hashtext() for the three new ledger table names against a live local PostgreSQL 17.11 and confirmed no collisions among these three or with the existing six (all nine values distinct). Updated packages/migration-runner/README.md's collision note from six to nine verified names, and named the PostgreSQL version tested against.

  • Added @corbits/workflow-deploy-source to docs/package-migrations.md's "Self-contained, transactional" package list — it was auditing-scope for CL-7241 but missing from that list even though it already used the byte-for-byte identical shape; webhook-triggers and routines were already (pre-emptively / inaccurately, pre-conversion) listed there and are now accurate.

  • Minor, non-blocking: converting webhook-triggers and routines drops the JSON.stringify(...) quoting their pre-existing migration-failure error messages used around the migration name (e.g. migration "0001_routine" failed becomes migration 0001_routine failed) — applyPackageMigrations interpolates the bare name. workflow-deploy-source was already unquoted pre-conversion, so it's unaffected. Confirmed nothing outside migration-runner's own tests parses this string. Flagging since PR migration-runner: shared advisory-lock guard for package migrations #480's own conversions had the same effect on whichever of its six packages used the quoted form.

hashtext values (PostgreSQL 17.11)

ledger table hashtext()
access_policy_migrations -1263132300
bench_migrations 1753525330
evals_migrations -636957134
inference_catalog_migrations -723349846
insights_migrations 1498834098
preferences_migrations 657047452
webhook_triggers_migrations -757578924
routine_migrations -1309120395
workflow_deploy_source_migrations 1026438117

All nine distinct — no collisions.

Test plan

  • cd packages/webhook-triggers && bun run typecheck && bun test — clean (37 pass, including new concurrency test)
  • cd packages/routines && bun run typecheck && bun test — clean (272 pass, including new concurrency test)
  • cd packages/workflow-deploy-source && bun run typecheck && bun test — clean (13 pass, including new concurrency test)
  • bunx prettier --check on touched files — clean
  • bun run lint — clean (0 errors; pre-existing unrelated warnings)
  • bun run check:structural — clean, including check:licenses
  • CI (gh pr checks) — pending

CL-7241

…ploy-source migrations

Two hub replicas calling these packages' migration runners at once each
see no ledger row and race the check-then-insert loop, crashing the
loser on a duplicate-key violation (CL-7241). These tests reproduce
that race directly against the current implementation and currently
fail, matching CL-7211/PR #480's own before/after pattern for the six
packages already converted to the shared advisory-lock guard.
…workflow-deploy-source

Converts these three packages' migration runners to call
@corbits/migration-runner's applyPackageMigrations, exactly as CL-7211
converted the other six (bench, insights, preferences,
inference-catalog, evals, access-policy). Closes the same
check-then-act race: two hub replicas booting together no longer both
see a migration as unapplied and crash the loser on a duplicate-key
ledger insert.

Schema and ledger table names, and every exported function's name and
signature, are unchanged, so this is safe for databases with an
already-populated ledger and requires no caller changes.
…-deploy-source under the shared runner shape

@corbits/migration-runner's README now reflects all nine ledger tables
using the shared advisory-lock guard (six from CL-7211, three from
CL-7241), pairwise verified collision-free against a live PostgreSQL
17.11 hashtext(). docs/package-migrations.md's shape-1 package list
already named webhook-triggers and routines even before this PR
converted them; workflow-deploy-source was missing from that list
entirely and is added now that it also uses the shared runner.
@TheGreatAxios
TheGreatAxios force-pushed the cl-7241-migration-advisory-lock-rollout branch from 29fbd83 to baf72d1 Compare August 30, 2026 21:33
@TheGreatAxios
TheGreatAxios merged commit 86adec2 into main Aug 30, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant