-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
sync: oneshot::Receiver::is_terminated()
#7152
sync: oneshot::Receiver::is_terminated()
#7152
Conversation
This comment was marked as resolved.
This comment was marked as resolved.
> You could also add a test for `is_terminated` before and after > `try_recv` as well. tokio-rs#7152 (comment) Co-authored-by: M.Amin Rayej <[email protected]> Signed-off-by: katelyn martin <[email protected]>
this commit introduces a new method to `tokio::sync::oneshot::Receiver<T>`. broadly speaking, users of the oneshot channel are encouraged to `.await` the `Receiver<T>` directly, as it will only yield a single value. users implementing their own `std::future::Future`s directly may instead poll the receiver via `<Receiver<T> as Future<Output = Result<T, RecvError>::poll(..)`. note that the contract of `Future::poll()` states that clients should not poll a future after it has yielded `Poll::Ready(value)`. this commit provides a way to inspect the state of a receiver, to avoid violating the contact of `Future::poll(..)`, or requiring that a oneshot channel users track this state themselves externally via mechanisms like `futures::future::FusedFuture`, or wrapping the receiver in an `Option<T>`. NB: this makes a small behavioral change to the implementation of `<Receiver<T> as Future<Output = Result<T, RecvError>::poll(..)`. this change is acceptable, per the `Future::poll()` documentation regarding panics: > Once a future has completed (returned Ready from poll), calling its poll method again may panic, block forever, or cause other kinds of problems; the Future trait places no requirements on the effects of such a call. the upside of this is that it means a broken or closed channel, e.g. when the sender is dropped, will settle as "finished" after it yields an error. see: * tokio-rs#7137 (comment) * https://doc.rust-lang.org/stable/std/future/trait.Future.html#panics Signed-off-by: katelyn martin <[email protected]>
> You could also add a test for `is_terminated` before and after > `try_recv` as well. tokio-rs#7152 (comment) Co-authored-by: M.Amin Rayej <[email protected]> Signed-off-by: katelyn martin <[email protected]>
036c002
to
8fc0759
Compare
NB: this commit means that this branch (tokio-rs#7153) is dependent upon interfaces proposed in (tokio-rs#7152). pr tokio-rs#7152 proposes a `is_terminated()` method for the oneshot channel's receiver. that is the proper method to use to check whether or not it is safe to poll a oneshot receiver as a future. this commit adds a note cross-referencing this method to the documentation of `is_empty()`, to help mitigate misuse. this method only reports whether a value is currently waiting in the channel; a channel that has already received and yielded a value to its receiver is also empty, but would panic when polled. Signed-off-by: katelyn martin <[email protected]>
NB: this commit means that this branch (tokio-rs#7153) is dependent upon interfaces proposed in (tokio-rs#7152). pr tokio-rs#7152 proposes a `is_terminated()` method for the oneshot channel's receiver. that is the proper method to use to check whether or not it is safe to poll a oneshot receiver as a future. this commit adds a note cross-referencing this method to the documentation of `is_empty()`, to help mitigate misuse. this method only reports whether a value is currently waiting in the channel; a channel that has already received and yielded a value to its receiver is also empty, but would panic when polled. Signed-off-by: katelyn martin <[email protected]>
Signed-off-by: katelyn martin <[email protected]>
Thanks. |
NB: this commit means that this branch (tokio-rs#7153) is dependent upon interfaces proposed in (tokio-rs#7152). pr tokio-rs#7152 proposes a `is_terminated()` method for the oneshot channel's receiver. that is the proper method to use to check whether or not it is safe to poll a oneshot receiver as a future. this commit adds a note cross-referencing this method to the documentation of `is_empty()`, to help mitigate misuse. this method only reports whether a value is currently waiting in the channel; a channel that has already received and yielded a value to its receiver is also empty, but would panic when polled. Signed-off-by: katelyn martin <[email protected]>
Lol this started causing some panics in production for us. Misuse on our part but it was a tricky one to root cause |
@rushilmehra Can you describe it in a separate issue? I think this change is not supposed to affect the existing code. |
We were accidentally polling a oneshot receiver after it was complete, honestly just misuse on our side. |
this commit introduces a new method to
tokio::sync::oneshot::Receiver<T>
.broadly speaking, users of the oneshot channel are encouraged to
.await
theReceiver<T>
directly, as it will only yield a single value.users implementing their own
std::future::Future
s directly may instead poll the receiver via<Receiver<T> as Future<Output = Result<T, RecvError>::poll(..)
. note that the contract ofFuture::poll()
states that clients should not poll a future after it has yieldedPoll::Ready(value)
.this commit provides a way to inspect the state of a receiver, to avoid violating the contact of
Future::poll(..)
, or requiring that a oneshot channel users track this state themselves externally via mechanisms likefutures::future::FusedFuture
, or wrapping the receiver in anOption<T>
.NB: this makes a small behavioral change to the implementation of
<Receiver<T> as Future<Output = Result<T, RecvError>::poll(..)
. this change is acceptable, per theFuture::poll()
documentation regarding panics:the upside of this is that it means a broken or closed channel, e.g. when the sender is dropped, will settle as "finished" after it yields an error.
see:
oneshot::Receiver::{is_empty, is_closed}
#7137 (comment)