Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move owned WebSocket back to api::WebSocket on final hibernation event #664

Merged
merged 2 commits into from
May 18, 2023

Conversation

MellowYarker
Copy link
Contributor

We saw a situation where queued websocket messages (send()/close()) that were inserted during the webSocketClose event failed to deliver. This was caused by the fact that the HibernationManager drops HibernatableWebSocket's after their final close/error event is dispatched.

Unfortunately, the HibernatableWebSocket would get dropped too soon, so the underlying kj::WebSocket was no longer available to send messages.

We fix this by moving the owned kj::Own<kj::WebSocket> out from the HibernatableWebSocket and back into the api::WebSocket's NativeState after dispatching the final close/error event. NativeState's lifetime is managed by the IoContext's DeleteQueue, so it lives long enough to flush the remaining messages.

@jclee
Copy link
Contributor

jclee commented May 18, 2023

(Just as another bit of cleanup I noticed, probably want to mark the destructors for HibernationManagerImpl and HibernatableWebSocket as noexcept(false).)

Copy link
Contributor

@bcaimano bcaimano left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, nicely done!

src/workerd/api/hibernatable-web-socket.c++ Outdated Show resolved Hide resolved
src/workerd/api/hibernatable-web-socket.c++ Outdated Show resolved Hide resolved
src/workerd/api/web-socket.h Outdated Show resolved Hide resolved
src/workerd/io/hibernation-manager.h Outdated Show resolved Hide resolved
@@ -699,7 +699,7 @@ void WebSocket::ensurePumping(jsg::Lock& js) {
KJ_FAIL_ASSERT("Unexpected native web socket state", native.state);
}
}
}, [this](jsg::Lock& js, jsg::Value&& exception) mutable {
}, [this, thisHandle = JSG_THIS](jsg::Lock& js, jsg::Value&& exception) mutable {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As an alternative here, the JSG_THIS could be attached to the kj::Promise returned by the then(...) rather than captured by the lambda. Would save having to grab it twice. Obviously not a big deal tho.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose, longer term, we'd want these to maybe be JSG_VISITABLE_LAMBDA()s, so that the garbage collector had visibility into them? But that seems to be a preexisting issue.

@MellowYarker MellowYarker force-pushed the milan/hibernation-lifetime branch 2 times, most recently from bba7237 to 100e65a Compare May 18, 2023 18:46
@jclee jclee self-requested a review May 18, 2023 19:59
We saw a situation where queued websocket messages (send()/close()) that
were inserted during the webSocketClose event failed to deliver. This
was caused by the fact that the HibernationManager drops
HibernatableWebSocket's after their final close/error event is
dispatched.

Unfortunately, the HibernatableWebSocket would get dropped too soon, so
the underlying kj::WebSocket was no longer available to send messages.

We fix this by moving the owned kj::Own<kj::WebSocket> out from the
HibernatableWebSocket and back into the api::WebSocket's NativeState
after dispatching the final close/error event. NativeState's lifetime
is managed by the IoContext's DeleteQueue, so it lives long enough to
flush the remaining messages.
Related to the hibernation work; we noticed a few other things that
could potentially lead to problems.
@MellowYarker MellowYarker merged commit ca0825b into main May 18, 2023
@MellowYarker
Copy link
Contributor Author

Thanks for reviewing!

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.

5 participants