Aligns Connection.recv(timeout=0) with docstring
#1571
Closed
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.
Fix #1552
NOTE: I added a couple of tests, but one of the two is still not passing. My intention is to fix and then squash the fix into this commit. At which point, this note will be removed.
The docstring for
Connection.recvsuggests that if you provide the argumenttimeout=0, you can retrieve any message in waiting:"Set
timeoutto0to check if a message was already received."Current behavior is that this does nothing and instead makes a
TimeoutErrorimmediately throw on the first use of a derivedDeadline.However, being able to check for a full message without blocking unneccesarily (aka, waiting for the server to send a message) would be useful, especially if your websocket client needs to be able to continue to do work in another thread and so periodically ceding control is important.
Most of the problem comes from the fact that the code doesn't treat a timeout value of 0 as special, and the code path will create a
Deadlinewith it, and then rely on the side effects of blocking network I/O and exceptions in order to guarantee the contract ofConnection.recv()which is to ultimately deliver a full message.The error has been addressed by allowing the API of
Assembler.get()to potentially returnNonewhen a new param,peek, is set to True (the default is False and maintains previous behavior). The intention of this param is to allow the method to acquire the class's mutex, check if there are any frames in theAssemblerinstance, and if not, returnNone. The only place where this param is used is withinConnection.recv(), which is now able to treat the exceptional case oftimeout=0by setting up it's arguments toAssembler.get()without otherwise changing its code path.Tests:
Nonewhentimeout=0and the underlying frames queue is empty, and another that returns the correct message when the underlying frames queue has a frame.