pub struct Receiver<T> { /* private fields */ }Expand description
Receives a value from the associated Sender.
A Sender and a Receiver are created together by channel. The
receiver is itself a Future: await it to get a
Result<T, error::RecvError>. There is no recv
method.
Polling a receiver never fails spuriously: a value sent before a poll starts is returned by that poll.
§Cancel safety
Awaiting a &mut Receiver<T> is cancel safe. If it is a branch of a
select and another branch completes first, no value was received on this
channel.
§Panics
Polling a receiver again after it completed (it returned Ready, or
try_recv returned a value or
TryRecvError::Closed) panics with called after complete. Check
is_terminated first.
use nuclei::sync::oneshot;
use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Poll, Waker};
let (tx, mut rx) = oneshot::channel();
let mut cx = Context::from_waker(Waker::noop());
assert_eq!(Pin::new(&mut rx).poll(&mut cx), Poll::Pending);
tx.send(7).expect("the receiver is still there");
assert_eq!(Pin::new(&mut rx).poll(&mut cx), Poll::Ready(Ok(7)));
assert!(rx.is_terminated());Implementations§
Source§impl<T> Receiver<T>
impl<T> Receiver<T>
Sourcepub fn close(&mut self)
pub fn close(&mut self)
Prevents the associated Sender from sending a value.
Any send that happens after close returns fails. A value sent
before close can still be taken with try_recv
(or by polling). This makes a graceful shutdown possible: close, then
drain.
close does nothing if the value was already received or the
channel is already closed. Wait-free.
use nuclei::sync::oneshot;
let (tx, mut rx) = oneshot::channel();
tx.send("sent before").expect("the receiver is still there");
rx.close();
assert_eq!(rx.try_recv(), Ok("sent before"));
let (tx, mut rx) = oneshot::channel();
rx.close();
assert!(tx.is_closed());
assert_eq!(tx.send("too late"), Err("too late"));Sourcepub fn is_terminated(&self) -> bool
pub fn is_terminated(&self) -> bool
Whether this receiver already completed: it returned its value or an error, so it must not be polled again.
use nuclei::sync::oneshot;
let (tx, mut rx) = oneshot::channel();
assert!(!rx.is_terminated());
tx.send(0).expect("the receiver is still there");
assert!(!rx.is_terminated(), "a value that was sent but not read");
assert_eq!(rx.try_recv(), Ok(0));
assert!(rx.is_terminated());Sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Whether the channel holds no value.
true before a send, after the sender was dropped, and after the
receiver completed. It is not a promise that polling is safe: use
is_terminated for that.
use nuclei::sync::oneshot;
let (tx, rx) = oneshot::channel();
assert!(rx.is_empty());
tx.send(0).expect("the receiver is still there");
assert!(!rx.is_empty());Sourcepub fn try_recv(&mut self) -> Result<T, TryRecvError>
pub fn try_recv(&mut self) -> Result<T, TryRecvError>
Attempts to receive a value without waiting.
The current task is not registered for a later wake. Unlike a poll, it cannot fail spuriously: any send or close that happened before the call is reported. Wait-free.
Ok(value)when a value is waiting.Err(TryRecvError::Empty)when none was sent yet.Err(TryRecvError::Closed)when the sender was dropped without sending, the channel was closed empty, or the value was received already.
use nuclei::sync::oneshot::{self, error::TryRecvError};
let (tx, mut rx) = oneshot::channel();
assert_eq!(rx.try_recv(), Err(TryRecvError::Empty));
tx.send("hello").expect("the receiver is still there");
assert_eq!(rx.try_recv(), Ok("hello"));
assert_eq!(rx.try_recv(), Err(TryRecvError::Closed));Sourcepub fn blocking_recv(self) -> Result<T, RecvError>
pub fn blocking_recv(self) -> Result<T, RecvError>
Receives the value on this thread, parking the thread until it arrives.
For use outside asynchronous code. On a nuclei shard (inside one of its tasks) it does not park the thread: it runs a nested block_on, so the shard keeps running its other tasks meanwhile. Inside another runtime’s task
it blocks that task’s executor thread, so do not. It is not wait-free:
waiting for the sender is what it does.
§Panics
Panics if the receiver already completed; see Receiver. On
wasm32, where no other thread can send, it also panics when the
value is not there already: the call could never end.
use nuclei::sync::oneshot;
let (tx, rx) = oneshot::channel::<u8>();
let sender = std::thread::spawn(move || tx.send(10));
assert_eq!(rx.blocking_recv(), Ok(10));
sender.join().expect("sender thread").expect("the receiver was waiting");