feat: adopt Cloudflare WebSocket Hibernation API#137
Draft
kptdobe wants to merge 1 commit into
Draft
Conversation
Contributor
|
In theory this seems like a good idea. I don't have any experience with the hibernation API so we need to make sure that we test it very well. @karlpauls any thoughts? |
Use ctx.acceptWebSocket() instead of ws.accept() so the Durable Object survives WebSocket disconnects without losing in-flight Yjs state. Added webSocketMessage/webSocketClose/webSocketError class methods for CF's Hibernation routing, with serializeAttachment/deserializeAttachment to restore auth context after hibernation. setupWSConnection gains a hibernation flag to skip addEventListener registration when CF handles routing directly. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
f0ce60b to
354428d
Compare
Contributor
Author
|
Need more testing, moving to draft PR. |
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.
Problem
During image drag-and-drop sessions in DA, Durable Objects are evicted when the browser briefly drops WebSockets (while busy uploading blobs). Each eviction clears the in-memory
docsMap. On reconnect,bindStatere-fetches from da-admin and triggers a 1-second revert timer, causing the just-inserted images to disappear.Root cause
webSocket.accept()(the non-Hibernation API) causes the DO to be evicted whenever a WebSocket disconnects. Any work in flight (debounced saves,bindStateasync chain) is cancelled withOutcome: "canceled", and the in-memory Yjs state is lost.Solution
Adopt the Cloudflare WebSocket Hibernation API (
ctx.acceptWebSocket()), which keeps the DO alive across WebSocket disconnects:DocRoom.fetch()callsthis.ctx.acceptWebSocket(server)+server.serializeAttachment({ docName, auth, authActions })instead ofserver.accept()webSocketMessage,webSocketClose,webSocketErrorhandle CF Hibernation routingsetupWSConnectiongains ahibernationflag (defaultfalse) — whentrue, skipsaddEventListenerregistration since CF calls the class methods directlyhandleWebSocketMessageandhandleWebSocketCloseinshareddoc.jsallowwebSocketMessage/webSocketCloseto re-hydrate Yjs state after a cold startTests
ctx.acceptWebSocketmock +serializeAttachmentbindState),webSocketClosecleanup,webSocketErrorcleanup, no-op close on unknown doc, read-only auth restoration🤖 Generated with Claude Code