-
Notifications
You must be signed in to change notification settings - Fork 579
client-api: Rewrite websocket loop #2906
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
base: master
Are you sure you want to change the base?
Conversation
Split the websocket stream into send and receive halves and spawns a new tokio task to handle the sending. Also move message serialization + compression to a blocking task if the message appears to be large. This addresses two issues: 1. The `select!` loop is not blocked on sending messages, and can thus react to auxiliary events. Namely, when a module exits, we want to terminate the connection as soon as possible in order to release any database handles. 2. Large outgoing messages should not occupy tokio worker threads, in particular when there are a large number of clients receiving large intial updates.
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.
I'd like to figure out what's going on with the SerializeBuffer
and fix it before merging, but otherwise this looks good to me.
Also close the messages queue after the close went through. Accordingly, closed and exited are the same -- we can just drop incoming messages when closed.
Updated to:
I think that we should also clear the message queue and cancel outstanding execution futures in the latter case, but that can be left to a future change. |
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.
I looked through this for a while, and I'm still not very confident that I understand the error cases. I think we should do some bot testing with this to see what effect it has, but I think I'd like to try writing some tests for this, so we can trigger some of these tricky cases.
Also fixes the actual resource hog, which is that the ws_actor never terminated because all receive errors were ignored.
Update to:
|
Updated to:
|
Updated to:
|
Pong frames sit in line with previously sent messages, and so may not be received in time if the server is backlogging. We also want to time out the connection in "cable plugged" scenarios, where the kernel doesn't consider the connection gone until `tcp_keepalive_time`.
Also losen `Unpin` requirements and use long names for type variables denoting futures.
Split the websocket stream into send and receive halves and spawns a
new tokio task to handle the sending. Also move message serialization +
compression to a blocking task if the message appears to be large.
This addresses two issues:
The
select!
loop is not blocked on sending messages, and can thusreact to auxiliary events. Namely, when a module exits, we want to
terminate the connection as soon as possible in order to release any
database handles.
Large outgoing messages should not occupy tokio worker threads, in
particular when there are a large number of clients receiving large
intial updates.
Expected complexity level and risk
4 - The state transitions remain hard to follow.
Testing
and observed no hangs / delays (which I did before this patch).
In reconnection scenarios, all clients where disconnected timely, but
could reconnect almost immediately.