-
Notifications
You must be signed in to change notification settings - Fork 664
sdk: Client ping on idle connections #2309
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
Conversation
Make the websocket loop send a `Ping` frame when the connection is idle for a while. "idle" includes missing server-side pings. Writing to the socket will detect if the remote end went away, but FIN / RST went missing for some reason. This is not detected by only reading.
081ce29 to
abda910
Compare
|
After out-of-band discussion, we've decided we'd like to include this in the 1.0 release if possible, though if it can't go in we won't be too disappointed. It seems low-risk, and will improve visibility for networking failures, particularly in SpacetimeDB-cloud. |
gefjon
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, just realized: the host doesn't actually respond Pong to client Pings. crates/client-api/src/routes/subscribe.rs has:
Item::Message(ClientMessage::Ping(_message)) => {
log::trace!("Received ping from client {}", client.id);
// TODO: should we respond with a `Pong`?
}I don't think we can merge this until we complete that TODO comment. I'm worried that as-is, this patch will cause spurious disconnects.
gefjon
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope, I'm wrong. Per this discussion, Tungstenite responds Pong to Pings automatically.
Make the websocket loop send a
Pingframe when the connection is idle for a while. "idle" includes missing server-side pings.Writing to the socket will detect if the remote end went away, but FIN / RST went missing for some reason. This is not detected by only reading.
I haven't touched the scary server-side websocket loop, but we may consider to also make it send pings only if it doesn't have anything else to send.
Expected complexity level and risk
2
Testing
The situation can be approximated by inducing a 100% packet loss scenario.
This can be done in various ways. A convenient one is
docker compose disconnect, which disables the virtual interface of a container.Without this patch, you'll see the server timing out the connection after a while (as it did not receive pong), while the client keeps thinking that something may eventually arrive.
With this patch, both ends eventually close the connection.