Fixed possible starvation issue during upgrading to WebSocket transport #16
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.
This pull request fixes a possible starvation issue that prevents the socket from being upgraded from polling to WebSocket transport if the outbound packet queue is filled too fast from other (green) threads.
I have stumbled upon the issue while building a WebSocket service that generates packets with a high frequency. In our case, the packets represent measurements that come from external devices with a frequency > 100 Hz, so there are more than 100 packets per second. When a new client tried to connect to the service, we have found that the upgrade to the WebSocket transport blocked in the line where we were waiting for the outbound packet queue to become empty (i.e. a
self.queue.join()
call). This happened because the polling transport was not fast enough to drain the packet queue faster than it was filled from the other end by the measurement thread. (The WebSocket transport would have been fast enough, though).The patch fixes the problem by storing outbound packets generated during the upgrade in a temporary "backlog" queue so the "real" outbound queue has a chance to become empty, allowing the transport upgrade to proceed. When the transport is upgraded to WebSocket, the backlog is flushed and then the backlog queue is deleted.