Failed first boot leaves background workers off until restart #65

Closed
opened 2026-10-08 16:33:29 -04:00 by goddard · 1 comment
Collaborator

hooks.server.ts:11-19 sets booted = true before migrate(). If that first migration fails (for example, the one-time VACUUM runs out of disk), later requests retry and the UI loads, but startWorker() never runs. That means no provisioning, monitoring, autoscaling or maintenance, and nothing reports it.

Fix

  • Move startup into SvelteKit's init hook (the project is on 2.70), or set the flag only after migration and worker start succeed.
`hooks.server.ts:11-19` sets `booted = true` before `migrate()`. If that first migration fails (for example, the one-time VACUUM runs out of disk), later requests retry and the UI loads, but `startWorker()` never runs. That means no provisioning, monitoring, autoscaling or maintenance, and nothing reports it. **Fix** - Move startup into SvelteKit's `init` hook (the project is on 2.70), or set the flag only after migration and worker start succeed.
goddard added the
priority
medium
type/bug
labels 2026-10-08 16:39:10 -04:00
josh was assigned by goddard 2026-10-08 17:31:46 -04:00
Author
Collaborator

Reviewed 0abe5ba820. The fix is done, so I'm closing this.

Checklist

  • Flag set only after startup succeeds. booted is now set at the end of boot() (hooks.server.ts:25), after migration, deployment recovery, worker start and the performance monitor. If any of them throws, the request fails before reaching the UI, and the next request retries the whole boot. The new test runs each of the four steps as the failing one and checks retries, ordering, and that authentication isn't reached until boot succeeds.

Review notes

  • I checked that a retry can't leave the workers half-started. startWorker sets its own guard before starting the timers, but nothing between them can throw synchronously: tick() and fanoutStatus() are async, and their failures are caught.
  • The 5 affected test files pass locally (105 tests), the full suite passes (208 files, 2,625 tests), and npm run check reports 0 errors.
Reviewed 0abe5ba8205378cc91a0ca8fd63a4982af35fefd. The fix is done, so I'm closing this. **Checklist** - [x] **Flag set only after startup succeeds.** `booted` is now set at the end of `boot()` (`hooks.server.ts:25`), after migration, deployment recovery, worker start and the performance monitor. If any of them throws, the request fails before reaching the UI, and the next request retries the whole boot. The new test runs each of the four steps as the failing one and checks retries, ordering, and that authentication isn't reached until boot succeeds. **Review notes** - I checked that a retry can't leave the workers half-started. `startWorker` sets its own guard before starting the timers, but nothing between them can throw synchronously: `tick()` and `fanoutStatus()` are async, and their failures are caught. - The 5 affected test files pass locally (105 tests), the full suite passes (208 files, 2,625 tests), and `npm run check` reports 0 errors.
Sign in to join this conversation.