fix(client): discard timed-out packets from the Engine.IO buffer - #5560
Open
dyk1454683243-sudo wants to merge 1 commit into
Open
dyk1454683243-sudo wants to merge 1 commit into
dyk1454683243-sudo wants to merge 1 commit into
Conversation
When an acknowledgement times out, Socket.IO already drops the packet from its own send buffer. If the socket is still considered connected, the event has already been written to the Engine.IO write buffer and was later flushed once the transport became writable again. Remove those unflushed Engine.IO packets on timeout, but keep a multi-packet payload intact if any fragment was already handed to the transport. Fixes socketio#4318 Co-authored-by: David <dyk1454683243-sudo@users.noreply.github.com>
darrachequesne
left a comment
Member
There was a problem hiding this comment.
Hi! Thanks a lot for the pull request, please find my comments below.
| return; | ||
| } | ||
|
|
||
| for (let i = 0; i < this._prevBufferLen; i++) { |
Member
There was a problem hiding this comment.
I think there is a edge case here, in case of a Socket.IO binary packet sent as multiple Engine.IO packets:
- the first packet is sent successfully
- "drain" is emitted and
_prevBufferLenis set to 0 - the attachments remains in the Engine.IO buffer and are then removed by
_removeFromWriteBuffer() - the server-side Socket.IO parser is left waiting for attachments that will never arrive
Member
|
Alternative fix to #4318:
Something like: interface WriteOptions {
compress?: boolean;
discardGroupId?: number;
discardAfter?: number;
}Which would keep Engine.IO as the owner of its own write buffer and avoid Socket.IO calling into a new Engine.IO buffer API. What do you think? Related: #5546 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The kind of change this PR does introduce
Current behavior
An event emitted with
timeout()while the connection is still considered open can already be sitting in the Engine.IO write buffer (transport temporarily unwritable, for example after a network disruption that has not closed the socket yet).When the acknowledgement times out, Socket.IO removes the packet from its own
sendBuffer, but the encoded Engine.IO packet remains queued. Restoring the network / making the transport writable again flushes that timed-out event to the server.This is #4318.
New behavior
On acknowledgement timeout the client also removes every Engine.IO packet created from that Socket.IO event, as long as none of them has been handed to the transport yet.
If any encoded packet is already part of the current flush batch, all related packets are left intact so a binary event cannot be partially transmitted.
Neighboring in-flight events are still flushed normally.
Other information (e.g. related issues)
Fixes #4318.
Regression coverage: