Fix mixin type mismatch and document the untested hibernation wake path#24
Merged
Conversation
webSocketClose and webSocketError were declared as returning Promise<void> while the mixin's overrides return void synchronously (nothing to await -- both just drop bookkeeping for the closed socket). Retype both to void | Promise<void>, matching @cloudflare/workers-types's own DurableObject interface and the actual implementation. webSocketMessage is genuinely async and is unchanged. Verified the emitted dist/server/mixin.d.ts reflects the new signature after build; no runtime behavior changes. Codex review finding. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The host-matrix suite (ADR-0015) pins the cohosting tag-partition contract on a single live instance, but never forces a real hibernation eviction, so the wake-time restore itself (getWebSockets(SYNC_TAG) in the mixin's constructor) is verified by code-reading only, not by an automated test. Investigated whether @cloudflare/vitest-pool-workers can simulate that: evictDurableObject/evictAllDurableObjects do exactly this (graceful evict, storage preserved, WebSockets hibernated not closed, instance reconstructed) but only from 0.16.20 onward, which requires vitest@^4 -- this repo pins vitest-pool-workers 0.12.21 against vitest 3.2.4, so pulling the helpers in means a major vitest bump. That is out of scope for this fix, so rather than fake the coverage, add an honest comment in the test file plus one ADR-0015 Consequences sentence naming the gap and the upgrade it is blocked on. Codex review finding. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This closes out two of three findings from a Codex review pass on the Syncable mixin work (PR #22 / #23). Here is where each finding landed.
Finding 1, the missing ORDER BY rowid guard on WITHOUT ROWID tables. This was real, but it was already fixed on main before this branch was cut, in PR #23 (commits ef4903a and 8f5005c). assertSyncCompatible now rejects a WITHOUT ROWID table and a table with a shadowing rowid column, both with a clear error at registerSync, and ADR-0015 already carries the corrected ordering note. No new work needed here. This PR just carries that history forward.
Finding 2, the mixin's declared WebSocket handler types did not match what they return. This was real and small. In src/server/mixin.ts, the SyncMixin interface declared webSocketClose and webSocketError as returning Promise, but the actual overrides return void synchronously since there is nothing to await, they just drop bookkeeping for a closed socket. This is now fixed. Both are retyped to void or Promise, which matches how Cloudflare's own DurableObject interface types these two handlers. webSocketMessage is genuinely async and was left alone. I checked the built dist/server/mixin.d.ts and confirmed it now emits the corrected signature.
Finding 3, the host-matrix test suite never forces a real hibernation wake. This is a real gap and I could not close it honestly. The cohosting guarantee depends on the mixin's constructor restoring only tagged sockets after a wake, but the in-CI suite only asserts the tag partition on a single live instance, it never tears the instance down and reconstructs it the way a real hibernation eviction would. I looked into whether the test tooling can simulate this. Cloudflare's vitest-pool-workers does now ship evictDurableObject and evictAllDurableObjects helpers that do exactly this, gracefully evicting a Durable Object while preserving storage and hibernating its WebSockets, then letting you observe the reconstructed instance. But those helpers only landed in vitest-pool-workers 0.16.20, which requires vitest 4. This repo is pinned to vitest-pool-workers 0.12.21 against vitest 3.2.4, so using them means a major vitest upgrade, which is out of scope for a small test-gap fix. Rather than fake this coverage, I added an honest comment in tests/host-matrix.test.ts explaining the gap and a matching sentence in ADR-0015's Consequences section naming the wake-time restore call site and the upgrade this is blocked on.
Test plan
🤖 Generated with Claude Code