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

Implement ping-pong for WebSocket clients #772

Merged
merged 40 commits into from
Jun 1, 2022
Merged

Implement ping-pong for WebSocket clients #772

merged 40 commits into from
Jun 1, 2022

Conversation

lexnv
Copy link
Contributor

@lexnv lexnv commented May 17, 2022

This PR exposes the ping-pong interface of the WebSocket clients.

A new ping_interval configuration is exposed for async-clients.
The ping interval represents the amount of time that should be elapsed between
an activity event (frontend event, backend event / pong frame received)
and submitting a ping frame to the RPC server.

From the RPC: https://www.rfc-editor.org/rfc/rfc6455#section-5.5.2

Upon receipt of a Ping frame, an endpoint MUST send a Pong frame in
response, unless it already received a Close frame. It SHOULD
respond with Pong frame as soon as is practical.

It is possible that the Pong reply is not submitted in the expected time
(ie if the server received a state_getKeys request that is taking minutes to finish).
Therefore the ping_interval is set to 5 minutes to capture those cases.

Closes #738.

lexnv added 6 commits May 17, 2022 16:49
Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
@lexnv lexnv requested a review from a team as a code owner May 17, 2022 16:00
@niklasad1
Copy link
Member

hehe, the idea behind the issue was to implement server-side pings based on what Jaco told us about JS-side of things here

however, I think this is useful for the client as well.

Copy link
Member

@niklasad1 niklasad1 left a comment

Choose a reason for hiding this comment

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

Looks good overall 👍

It would be better to make the extra ping/pongs optional and disable it by default.
I think there a might be a use case where one wants avoid this extra overhead to send these extra messages (not exactly sure but currently it's not possible to turn it off except a very long ping interval)

lexnv added 5 commits May 19, 2022 18:53
Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
core/src/client/mod.rs Outdated Show resolved Hide resolved
lexnv added 7 commits May 20, 2022 12:25
Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
) -> Result<(), Error> {

// Handle raw messages of form `ReceivedMessage::Bytes` (Vec<u8>) or ReceivedMessage::Data` (String).
async fn handle_recv_message<S: TransportSenderT>(
Copy link
Member

Choose a reason for hiding this comment

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

So I am under the impression the reason this is nested is this fn is only used locally within the scope of handle_backend_messages? I quite like it actually as it distinquishes the difference between handling frontend messages and backend message. 👍 Nice cleanup from it earlier being inside of the fn background_task. It's way easier to read/digest.


Some(FrontToBack::Batch(batch)) => {
tracing::trace!("[backend]: client prepares to send batch request: {:?}", batch.raw);
// NOTE(niklasad1): annoying allocation.
Copy link
Member

Choose a reason for hiding this comment

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

@niklasad1 DQ: Just wondering, I've seen this before and have wanted to ask, what specifically about the clone allocation is annoying here?

Copy link
Member

Choose a reason for hiding this comment

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

we can remove that note but it's just the those are batch ids are already owned in this scope and so should be possible to borrow that in theory but we use the HashSet entry which takes ownership of that + RequestManager` doesn't allow borrows for simplicity.

Copy link
Member

@TarikGul TarikGul left a comment

Choose a reason for hiding this comment

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

👍 Great Job!

@niklasad1 niklasad1 self-requested a review May 27, 2022 08:00
Copy link
Member

@niklasad1 niklasad1 left a comment

Choose a reason for hiding this comment

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

blocking this because of the trace logging thingy

core/Cargo.toml Outdated Show resolved Hide resolved
core/Cargo.toml Outdated Show resolved Hide resolved
lexnv and others added 7 commits May 27, 2022 12:34
Co-authored-by: Tarik Gul <47201679+TarikGul@users.noreply.github.com>
Co-authored-by: Tarik Gul <47201679+TarikGul@users.noreply.github.com>
Co-authored-by: Tarik Gul <47201679+TarikGul@users.noreply.github.com>
Co-authored-by: Tarik Gul <47201679+TarikGul@users.noreply.github.com>
Co-authored-by: Tarik Gul <47201679+TarikGul@users.noreply.github.com>
Co-authored-by: Niklas Adolfsson <niklasadolfsson1@gmail.com>
Co-authored-by: Niklas Adolfsson <niklasadolfsson1@gmail.com>
@@ -195,6 +197,20 @@ impl TransportSenderT for Sender {
Ok(())
}

/// Sends out a ping request. Returns a `Future` that finishes when the request has been
/// successfully sent.
Copy link
Collaborator

@jsdw jsdw May 27, 2022

Choose a reason for hiding this comment

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

Since we've been talking about cancel safety a bit, and not really relaetd to this PR, but do you reckon it is worth adding an issue to add docs to functions to note when they aren't cancel safe @niklasad1?

(or maybe almost no methods are cancel safe, and we state that up front and then note which ones are, perhaps)

Copy link
Member

Choose a reason for hiding this comment

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

sounds like a good idea.

lexnv added 2 commits May 27, 2022 13:03
Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
@lexnv lexnv requested a review from niklasad1 May 27, 2022 10:29
Copy link
Member

@niklasad1 niklasad1 left a comment

Choose a reason for hiding this comment

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

nice work, forgot about this one

@lexnv lexnv merged commit a0813cb into master Jun 1, 2022
@lexnv lexnv deleted the 738_ping_pong branch June 1, 2022 13:52
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.

[ws server]: add support periodic WS ping a.k.a "keep-alive"
4 participants