Skip to content

Do not create rolling-database list entries on syncOnly processes#38

Open
peachbits wants to merge 1 commit into
masterfrom
matthew/rolling-db-synconly-gate
Open

Do not create rolling-database list entries on syncOnly processes#38
peachbits wants to merge 1 commit into
masterfrom
matthew/rolling-db-synconly-gate

Conversation

@peachbits

@peachbits peachbits commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

CHANGELOG

Does this branch warrant an entry to the CHANGELOG?

  • Yes
  • No

Dependencies

none

Description

Fixes a split across the syncOnly gate in rolling-database setup that let a sync-only process register a period database it would never physically create.

In readDbList, appending an entry to the -list database (addDb) was ungated, but physical database creation runs inside setupDatabase only when !syncOnly. Since a cluster wires syncOnly: !cluster.isPrimary, a worker crossing a period boundary would write the spare/period list doc without creating the database. The database was only created later when the primary independently ran readDbList (startup, the 24h periodic task, or a -list onChange). If the primary's change notification was missed and its periodic tick had not elapsed, the database stayed missing, and once its active window opened, queries routed there returned 500 until a restart forced the primary's startup readDbList.

Changes:

  • Read syncOnly from the setup options inside setup (it was never destructured, so the list-mutation path could not observe it).
  • Gate the list-mutation blocks (empty-list backfill and future spare creation) behind !syncOnly, with a list.length > 0 guard on the spare block so an empty list cannot throw on list[0].startDate.

Now only the authoritative (non-syncOnly) process both writes the list doc and creates the database, in the same readDbList pass. Sync-only processes still pick up new databases through the existing -list onChange watcher.

Added a CHANGELOG entry under Unreleased. Verified with yarn types and yarn test.


Note

Medium Risk
Touches rolling-database lifecycle at period boundaries and query routing; change is narrow but correctness-critical for multi-cluster primary/worker setups.

Overview
Fixes a split where syncOnly workers could append period entries to the rolling *-list database while setupDatabase skipped creating the matching physical DB on those processes. That could leave queries routing to missing databases (500s) until the primary caught up.

readDbList in rolling-database.ts now reads syncOnly from setup options and runs empty-list backfill and future spare creation only when !syncOnly. The spare-period path also requires list.length > 0 so an empty list cannot dereference list[0]. Sync-only processes still load the list and react via the existing -list watcher; only the authoritative process both writes list docs and creates databases in the same pass.

CHANGELOG updated under Unreleased.

Reviewed by Cursor Bugbot for commit 0aa2413. Bugbot is set up for automated code reviews on this repo. Configure here.


A syncOnly process appended period/spare entries to the -list database
via addDb, but physical database creation is gated behind !syncOnly.
This let a sync-only process register a database it would never create,
so queries routing to that period would 500 until the primary process
independently ran readDbList.

Gate the list-mutation blocks behind !syncOnly so only the authoritative
process both writes the list doc and creates the database, in the same
readDbList pass.
@peachbits peachbits requested a review from paullinator July 2, 2026 22:12
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