Skip to content
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

Allow calling UnboundedReceiver::try_next after None #2369

Merged
merged 1 commit into from
Mar 1, 2021

Conversation

stepancheg
Copy link
Contributor

Do not panic.

Not-panicking is equally safe, and does not have negative performance
implication.

It is irrelevant for Stream implementation to panic or not (because
Stream behavior is unspecified after None), but panicking in
try_next just complicates the interface: returned Ok(None) is
reasonable assumption to have.

Consider this use case: drain the queue on drop by performing
app-specific cleanup of queued messages.

The obvious implementation would be:

impl Drop for MyReceiverWrapper {
    fn drop(&mut self) {
        while let Ok(Some(m)) self.try_next() {
            cleanup(m);
        }
    }
}

Without this change, I cannot even say for sure how this code need
to be implemented to avoid panicking. E. g. is is_closed enough
or some additional checks need to be performed?

Allow calling `UnboundedReceiver::try_next` and `Receiver::try_next`
after `None`: do not panic.

Not-panicking is equally safe, and does not have negative performance
implication.

It is irrelevant for `Stream` implementation to panic or not (because
`Stream` behavior is unspecified after `None`), but panicking in
`try_next` just complicates the interface: returned `Ok(None)` is
reasonable assumption to have.

Consider this use case: drain the queue on drop by performing
app-specific cleanup of queued messages.

The obvious implementation would be:

```
impl Drop for MyReceiverWrapper {
    fn drop(&mut self) {
        while let Ok(Some(m)) self.try_next() {
            cleanup(m);
        }
    }
}
```

Without this change, I cannot even say for sure how this code need
to be implemented to avoid panicking. E. g. is `is_closed` enough
or some additional checks need to be performed?
@stepancheg stepancheg requested a review from taiki-e as a code owner March 1, 2021 02:35
Copy link
Member

@taiki-e taiki-e left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! This seems to make sense to me. Could you also apply the same change to Receiver? I think it is preferable that their behavior is consistent.

futures-channel/src/mpsc/mod.rs Show resolved Hide resolved
@stepancheg
Copy link
Contributor Author

Done.

Copy link
Member

@taiki-e taiki-e left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@taiki-e taiki-e added 0.3-backport: pending The maintainer accepted to backport this to the 0.3 branch, but backport has not been done yet. A-channel Area: futures::channel labels Mar 1, 2021
@taiki-e taiki-e merged commit 4d2ad0e into rust-lang:master Mar 1, 2021
@stepancheg stepancheg deleted the try-next-none-none branch March 1, 2021 03:20
@taiki-e taiki-e mentioned this pull request Apr 10, 2021
@taiki-e taiki-e added 0.3-backport: completed and removed 0.3-backport: pending The maintainer accepted to backport this to the 0.3 branch, but backport has not been done yet. labels Apr 10, 2021
@taiki-e taiki-e mentioned this pull request Apr 10, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants