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.
Issue
The existing code in go-algorand is using two go-routines for reading/writing and a separate go-routine for opening/closing the connections.
When a client connection becomes non-responsive ( i.e. the writer is not returning ), the current implementation tries to close the connection. However, per WebSocket specification, the client is supposed to send a Close message first.
The close message is being sent using the
WriteControl
method, which is supposed to be able to run concurrently withWriteMessage
. However, both reachesConn.write
where it attempt to acquire a writing lock.Since the
WriteMessage -> Conn.write
is stuck ( but theWriteControl
doesn't really know it's stuck indefinitely ), theWriteControl -> Conn.write
get blocks indefinitely as well.Unlike the
WriteMessage
, when callingWriteControl
, we provide a deadline : a timestamp after which we don't care if the message was actually sent. In this PR, I have added handling that would limit the time theConn.write
would wait to that deadline.From spec perspective, it would be a violation of the WebSocket protocol; however, given that the other party is no longer responsive, a successful writing of a Close message is not possible, it would probably be just fine.