Skip to content

Conversation

@kim
Copy link
Contributor

@kim kim commented Feb 26, 2025

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.


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.

@kim kim requested review from coolreader18 and gefjon February 26, 2025 08:43
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.
@kim kim force-pushed the kim/sdk/client-ping branch from 081ce29 to abda910 Compare February 26, 2025 08:50
@kim kim enabled auto-merge February 26, 2025 15:41
@gefjon
Copy link
Contributor

gefjon commented Feb 26, 2025

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 gefjon disabled auto-merge February 26, 2025 15:44
Copy link
Contributor

@gefjon gefjon left a 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 gefjon added release-any To be landed in any release window and removed release-1.0 labels Feb 26, 2025
Copy link
Contributor

@gefjon gefjon left a 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.

@gefjon gefjon added release-1.0 and removed release-any To be landed in any release window labels Feb 26, 2025
@gefjon gefjon enabled auto-merge February 26, 2025 15:57
@gefjon gefjon added this pull request to the merge queue Feb 26, 2025
Merged via the queue into master with commit 55cd1e4 Feb 26, 2025
14 checks passed
@kim kim deleted the kim/sdk/client-ping branch February 27, 2025 10:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants