Skip to content

Keep database upgrades within edge request limits - #1845

Merged
stefan-burke merged 9 commits into
mainfrom
batch-migrations
Jul 16, 2026
Merged

Keep database upgrades within edge request limits#1845
stefan-burke merged 9 commits into
mainfrom
batch-migrations

Conversation

@stefan-burke

@stefan-burke stefan-burke commented Jul 16, 2026

Copy link
Copy Markdown
Member

Summary

  • Run at most four pending migrations in each edge request.
  • Batch migration history, schema markers, and lock release into fewer database calls.
  • Batch each atomic table rebuild inside its transaction, so one heavy migration can finish within the edge request limit.
  • Give each migration request its own lease, so an expired request cannot record progress or delete a newer request’s lock.
  • Continue unfinished upgrades safely on the next request.
  • Test upgrades from the free-text-question and listings-tag schemas under the real database round-trip guard.

Why

Sites with several pending migrations could exceed Bunny’s 50-subrequest request limit while starting. Splitting the work keeps each request within that limit while preserving completed migration progress. Batching table rebuild statements also prevents one heavy migration from exhausting the whole request before its progress can be saved. Lease-scoped completion keeps overlapping or stalled requests from changing each other’s migration state.

Risks

  • A POST that arrives while the new script is upgrading the database can receive the continuation page without being processed. We always move requests to the latest script and do not replay POST bodies across versions, so the user must submit that request again. This is an accepted deployment risk.

Testing

  • deno task precommit

Summary by CodeRabbit

  • Bug Fixes

    • Improved database migration reliability under limited round-trip budgets by batching migration marker recording.
    • Reworked migration locking to use request-scoped lease tokens, improving safety when lock ownership expires or marker/lock updates fail.
    • Strengthened migration schema restoration and ensured partial progress is preserved with correct completion marker behavior.
  • Tests

    • Added a migration “round-trip budget” test covering guarded/continuation upgrade edge cases.
    • Expanded migration runtime tests for lock TTL/ownership loss and aggregated error reporting.
  • Documentation

    • Added query-log scope helper and updated batching guidance for database transactions and rebuild-style table recreation.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 29411be317

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread test/shared/db/migration-round-trip-budget.test.ts
@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Migration initialization now executes migrations in request-sized batches, records progress and lock release atomically, and preserves partial progress after failures. Lock ownership and release failures are explicitly handled, with tests covering schema restoration, continuation behavior, and lock edge cases.

Changes

Migration batching and restoration

Layer / File(s) Summary
Transactional batch execution
src/shared/db/client.ts, src/shared/db/migrations/schema-sync.ts, test/shared/db/client/batch.test.ts, test/shared/db/link-table.test.ts
Transactions support batched statements, schema recreation uses transactional batching, and batch behavior plus transaction mocks are tested.
Budget-aware migration recording
src/shared/db/query-log.ts, src/shared/db/migrations.ts, src/shared/db/migrations/schema/version.ts
Migration markers use shared batch timestamps, pending migrations preserve partial progress, request-limited batches atomically record markers and release the lock, and request-specific lock tokens guard ownership.
Pre-migration schema restoration
test/lib/db/migration-restore/helpers.ts
Schema restoration drops migration-owned objects in reverse order and restores columns removed by specific migrations.
Round-trip continuation validation
test/shared/db/migration-round-trip-budget.test.ts
Database-backed tests validate schema setup, continuation failures, migration marker recording, and final update markers.
Lock ownership and failure validation
test/lib/db/migration-runtime.test.ts
Tests validate lost ownership, lock-release failures, and aggregated migration, marker, and unlock errors.
Migration runtime follow-up
TODO.md
The TODO records a planned split of migration locking, statement generation, and runtime execution into focused modules.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Request
  participant initDbUncached
  participant MigrationRunner
  participant Database
  Request->>initDbUncached: initialize database
  initDbUncached->>MigrationRunner: acquire request-specific lock token
  MigrationRunner->>Database: run request-sized migration batch
  MigrationRunner->>Database: verify token and record markers
  Database-->>MigrationRunner: release lock or retain it for continuation
  initDbUncached-->>Request: complete or report migration continuation
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: constraining database upgrades to edge request limits and continuing unfinished upgrades safely.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch batch-migrations

Comment @coderabbitai help to get the list of available commands.

@stefan-burke stefan-burke changed the title Batch migrations Keep database upgrades within edge request limits Jul 16, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/shared/db/migrations.ts`:
- Around line 699-708: Update the finally block in the migration flow around
releaseMigrationLock so release failures propagate instead of being caught and
reduced to a debug log. Preserve the original migration error when one already
exists, while ensuring a release failure is surfaced when it is the only
failure; remove the catch-and-continue behavior.
- Around line 521-524: Update acquireMigrationLock and its completion cleanup to
propagate an ownership token for the current lease, delete the settings row only
when both key and token match, and verify the token still owns the lease before
recording migration completion. Preserve the existing lock TTL and completion
behavior for the request that retains ownership.

In `@test/shared/db/migration-round-trip-budget.test.ts`:
- Line 73: Update the continuation-count assertion in the migration round-trip
test to derive the expected value from the production batch-size constant used
after LISTINGS_TAG_MIGRATION_ID. Export or reuse that constant from the
production migration code, import it in the test, and replace the hard-coded 3
while preserving the existing assertion behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 65cc146f-87e3-4d21-bdcd-4f387d93ec90

📥 Commits

Reviewing files that changed from the base of the PR and between fc04be2 and 4bfdc88.

📒 Files selected for processing (4)
  • src/shared/db/migrations.ts
  • src/shared/db/query-log.ts
  • test/lib/db/migration-restore/helpers.ts
  • test/shared/db/migration-round-trip-budget.test.ts

Comment thread src/shared/db/migrations.ts Outdated
Comment thread src/shared/db/migrations.ts Outdated
Comment thread test/shared/db/migration-round-trip-budget.test.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/shared/db/migrations.ts`:
- Around line 537-546: Update the catch branch surrounding
executeWhileMigrationLockOwned so failures writing completed migration markers
are captured instead of replacing the original migration error; when both
operations fail, throw an AggregateError containing both errors, while
preserving the original error when marker persistence succeeds. Add a regression
test covering the completed non-empty path where marker writing fails, and
verify both failures are retained.

In `@test/lib/db/migration-runtime.test.ts`:
- Around line 73-83: Update markMigrationPending and the related migration test
queries to use the shared production constants for schema_migrations,
migration_lock, latest_db_update, and db_schema_hash instead of hard-coded
identifiers. Import the existing constants from production code and substitute
them in every affected SQL statement, including the additionally referenced
range.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: ef17395e-f0bb-4d6e-8897-e3b4cb221563

📥 Commits

Reviewing files that changed from the base of the PR and between 4bfdc88 and 221bbce.

📒 Files selected for processing (2)
  • src/shared/db/migrations.ts
  • test/lib/db/migration-runtime.test.ts

Comment thread src/shared/db/migrations.ts
Comment thread test/lib/db/migration-runtime.test.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/shared/db/migrations.ts (1)

1-805: 📐 Maintainability & Code Quality | 🟠 Major | 🏗️ Heavy lift

File has grown well past the ~400-line guideline.

migrations.ts now spans to at least line 805 (per the diff's own line-range annotations for initDbUncached), several times the guideline size. This PR adds more logic on top (combinedFailures, recordMigrationBatch, runAcquiredMigrations, releaseAfterMigrationFailure, lock/lease handling) to an already large module. Consider splitting lock acquisition/release, batch-marker recording, and the pure migration-runner logic into separate focused modules, keeping I/O (DB calls) separate from pure logic per the same guideline.

As per coding guidelines, "Keep files under approximately 400 lines, splitting large modules and tests into focused files and separating pure logic from I/O."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/shared/db/migrations.ts` around lines 1 - 805, Split the oversized
migrations module into focused modules, keeping initDb orchestration and schema
migration behavior unchanged. Extract migration lock/lease operations around
acquireMigrationLock and releaseMigrationLock, batch marker recording around
recordMigrationBatch and related marker helpers, and pure migration execution
around runPendingMigrations/applyMigrationWithRetry into separate modules;
retain database I/O boundaries and update imports/exports accordingly.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/shared/db/migrations.ts`:
- Around line 1-805: Split the oversized migrations module into focused modules,
keeping initDb orchestration and schema migration behavior unchanged. Extract
migration lock/lease operations around acquireMigrationLock and
releaseMigrationLock, batch marker recording around recordMigrationBatch and
related marker helpers, and pure migration execution around
runPendingMigrations/applyMigrationWithRetry into separate modules; retain
database I/O boundaries and update imports/exports accordingly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: ff5f44ba-12cc-4bd6-929e-4ea328ccc132

📥 Commits

Reviewing files that changed from the base of the PR and between 221bbce and aeed410.

📒 Files selected for processing (3)
  • src/shared/db/migrations.ts
  • src/shared/db/migrations/schema/version.ts
  • test/lib/db/migration-runtime.test.ts

@stefan-burke

Copy link
Copy Markdown
Member Author

CodeRabbit’s outside-diff file-size comment is valid, but splitting the full migration subsystem is deliberately separate from this locking/budget safety change: migrations.ts already exceeded 700 lines before this PR, and combining a module move with concurrency behavior changes would make review and rollback riskier. Commit b0f799d records a standalone TODO.md task with concrete lock, marker-recording, runner, and orchestration boundaries plus the behavior and tests that must remain unchanged.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b0f799db48

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/shared/db/migrations.ts
Comment thread src/shared/db/migrations.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/shared/db/client.ts`:
- Around line 555-563: Update the batch callback to ensure every statement
passed to tx.batch is recorded through the existing query-tracking mechanism,
preserving the single database round trip. Reuse the same tracking behavior and
metadata used by execute, while retaining writtenSql, statementCount, and
enforceTransactionRoundTripGuard handling.

In `@test/shared/db/migration-round-trip-budget.test.ts`:
- Around line 35-40: Remove the uncovered defensive branch after the
MIGRATIONS.find call and use a documented non-null assertion for the migration
lookup, preserving the invariant that FREE_TEXT_MIGRATION_ID always exists.
- Around line 42-51: Update the stale-marker setup in the migration round-trip
test to read back both settings rows after the UPDATE and strongly assert that
each has value "stale" before calling initDb(). Keep the existing migration
deletion and initialization flow unchanged, using the test’s available database
query helpers.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 3173d48b-c392-4123-b9f8-c365ad9dccfd

📥 Commits

Reviewing files that changed from the base of the PR and between b0f799d and 4db4ee5.

📒 Files selected for processing (5)
  • src/shared/db/client.ts
  • src/shared/db/migrations/schema-sync.ts
  • test/shared/db/client/batch.test.ts
  • test/shared/db/link-table.test.ts
  • test/shared/db/migration-round-trip-budget.test.ts

Comment thread src/shared/db/client.ts
Comment thread test/shared/db/migration-round-trip-budget.test.ts
Comment thread test/shared/db/migration-round-trip-budget.test.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 943edb47c5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/shared/db/query-log.ts Outdated
@stefan-burke
stefan-burke added this pull request to the merge queue Jul 16, 2026
Merged via the queue into main with commit 43af8a2 Jul 16, 2026
3 checks passed
@stefan-burke
stefan-burke deleted the batch-migrations branch July 16, 2026 22:56
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