-
Notifications
You must be signed in to change notification settings - Fork 8
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
Avoid dropping of messages after breaking from Select
blocks
#42
Avoid dropping of messages after breaking from Select
blocks
#42
Conversation
d8fdef3
to
206bbd7
Compare
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
Alternative approach to frequenz-floss#42. Signed-off-by: Leandro Lucarella <[email protected]>
OK, I think I can conclude that Another option would be to implement our own This approach is not making the code simpler, but an advantage over this approach, IMHO, is that we keep the complexity in I gave it a shot by doing the mapping of the done coroutine returned by |
Not if we break the loop but keep the So I think you finally convinced me that we can't have both a nice simple and safe async iterator interface and not introduce the ready test to receivers. I really hate moving the complexity to channels implementators, but I guess there is no way around that is not moving complexity to users of |
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.
This looks good. I like it. It's also not that bad in terms of complexity as it only splits the work that needed to be done by receive()
, so I'm less worried about complexity for channels implementors too.
Before this PR we also had the issue about potential messages being lost when break
ing in Merge
/MergeNamed
, right?
This also needs a RELEASE_NOTES
entry!
In a followup PR I think we should definitely go for the async iterable interface for Select.ready()
, it will simplify the implementation too (as we won't need the extra class
for lazy evaluation for example).
Signed-off-by: Sahas Subramanian <[email protected]>
... instead of using `None` Signed-off-by: Sahas Subramanian <[email protected]>
Signed-off-by: Sahas Subramanian <[email protected]>
Signed-off-by: Sahas Subramanian <[email protected]>
.. and not in calls to `Select.ready()`, like it was earlier. Signed-off-by: Sahas Subramanian <[email protected]>
Signed-off-by: Sahas Subramanian <[email protected]>
Signed-off-by: Sahas Subramanian <[email protected]>
206bbd7
to
6f4576b
Compare
Needs a couple of documentation fixes and it is ready to go! Feel free to merge after those fixes. |
6f4576b
to
64e715d
Compare
... instead of `StopAsyncIteration` Signed-off-by: Sahas Subramanian <[email protected]>
64e715d
to
6138ee0
Compare
The current implementation of
Select.ready()
, instead of just checking that some of the receivers have messages, also fetches them.And in cases where there are multiple receivers with messages waiting to be read,
Select.ready()
consumes the latest message from each of them, and if subsequent user code decides to drop theSelect
object, and recreates it for some reason, the unprocessed messages thatSelect.ready()
had fetched will get lost.This is incorrect usage of
Select
, but the implementation should still try to ensure messages don't get dropped in such cases. This PR addresses this issue as follows:Receiver
interface now requires implementations to provide two private methods_ready
and_get
, which are used to implement__anext__
on the interface. SoReceiver
objects would retain the original interface with__anext__
, andreceive
, but now provide methods to only check if a message is ready or wait until one is, and a separate method to get a message after it becomes ready.Select.ready()
to use theReceiver._ready()
method to know when a message is ready and fetch the message with_get()
only when the user code is trying to fetch the message.Select
implementation no longer be able to operate on async iterators like it used to, but that's probably a good thing, taking away some of its power.