Skip to content

fix(runtime): wait on close for widget dev work already started, with a bound - #646

Merged
mrgoonie merged 1 commit into
mainfrom
fix/639-await-close-prune
Oct 8, 2026
Merged

mrgoonie merged 1 commit into
mainfrom
fix/639-await-close-prune

Conversation

@mrgoonie

@mrgoonie mrgoonie commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

Fixes #639. Refs #626, #631, #637.

What changed

  • WidgetDevSessions.close() now returns a promise. It stops watching every folder, then waits for each session's queued work, including a prune still removing a superseded snapshot with retries. The wait is bounded by closeWaitMs, which defaults to WIDGET_DEV_CLOSE_WAIT_MS (2 s). That covers one snapshot's full retry budget of about 1.5 s and fits inside the node's 5 s shutdown grace. Past the bound it logs that it is closing anyway and resolves.
  • The snapshot removal options are named in one place: SNAPSHOT_REMOVAL is the promise rm, with 5 retries and a 100 ms delay.
  • Shutdown path: RuntimeHandles gains closeWidgetDev(), and stopUpdateChecks() no longer closes widget dev sessions. main.ts starts closeWidgetDev() alongside the other stops and awaits it before the database closes. The only other callers are tests: slash-commands.spec.ts now awaits it.
  • widget-dev-sessions.spec.ts:
    • afterEach awaits close(), then await removeTestDirectory(dir) instead of rmSync.
    • The held-snapshot test is no longer timed against the retry budget. One attempt without retries meets the hold, which shows up as EBUSY or EPERM and is asserted on Windows. The holder is then released and has exited before the runtime's own removal runs. The test asserts that the runtime asked for SNAPSHOT_REMOVAL, with retries. Its outcome no longer depends on load.
    • New: waits on close for a superseded snapshot still being removed and stops waiting on close after its bound, .... The rm mock can now hold a removal open on a gate.

Verification

  • The two new tests fail against origin/main's widget-dev-sessions.ts: expected true to be false (close resolved during the prune) and expected 0 to be greater than or equal to 150. They pass on this branch.
  • Focused: widget-dev-sessions.spec.ts and slash-commands.spec.ts, 72 tests passed.
  • Parallel load on Windows 11: 8 concurrent vitest processes of widget-dev-sessions.spec.ts, 20 rounds. 160 passed, 0 failed. Some rounds overlapped a full pnpm verify.
  • pnpm typecheck, pnpm invariants (15/15, including test-cleanup-retries-asynchronously), eslint on the changed files, and pnpm verify (575 files passed) all pass.

No platform-specific behaviour was added. The hold assertion applies only on win32, where the hold has an effect.

Overlap: #644 also edits apps/runtime/test/widget-dev-sessions.spec.ts, in the folder-recreate test around line 1080. This PR's spec edits are the mock and afterEach near the top, and the held-snapshot test plus the new tests that follow it. No hunks are shared.

… a bound

`WidgetDevSessions.close()` now returns a promise that waits for every
session's queued work, including a superseded snapshot still being removed
with retries, for at most two seconds. The node's shutdown starts it with the
other stops and awaits it before the database closes.

The spec awaits `close()` and removes its folder with the async cleanup
helper. The held-snapshot test no longer races a 300 ms timer against the
retry budget: one attempt meets the hold, the holder exits, and then the
runtime's own removal runs, whose retry options are asserted.

Refs #626, #631
Fixes #639
@mrgoonie

mrgoonie commented Oct 8, 2026

Copy link
Copy Markdown
Contributor Author

Review attestation: ready to merge at 78bf243b83588b0ef6f1db22cf09e2d5fbd95b9d, reviewed by agent:code-reviewer.

A push to this PR makes this attestation stale; the new head needs its own review.

@mrgoonie
mrgoonie enabled auto-merge (squash) October 8, 2026 03:40
@mrgoonie
mrgoonie merged commit 732051d into main Oct 8, 2026
22 checks passed
@mrgoonie
mrgoonie deleted the fix/639-await-close-prune branch October 8, 2026 03:41
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.

Wait for in-flight snapshot pruning when widget dev sessions close

1 participant