Skip to main content

Receiver

Struct Receiver 

Source
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>

Source

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"));
Source

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());
Source

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());
Source

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));
Source

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");

Trait Implementations§

Source§

impl<T> Debug for Receiver<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T> Drop for Receiver<T>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more
Source§

impl<T> Future for Receiver<T>

Source§

type Output = Result<T, RecvError>

The type of value produced on completion.
Source§

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>

Attempts to resolve the future to a final value, registering the current task for wakeup if the value is not yet available. Read more

Auto Trait Implementations§

§

impl<T> !RefUnwindSafe for Receiver<T>

§

impl<T> !UnwindSafe for Receiver<T>

§

impl<T> Freeze for Receiver<T>

§

impl<T> Send for Receiver<T>
where T: Send,

§

impl<T> Sync for Receiver<T>
where T: Send,

§

impl<T> Unpin for Receiver<T>

§

impl<T> UnsafeUnpin for Receiver<T>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<F> IntoFuture for F
where F: Future,

Source§

type Output = <F as Future>::Output

The output that the future will produce on completion.
Source§

type IntoFuture = F

Which kind of future are we turning this into?
Source§

fn into_future(self) -> <F as IntoFuture>::IntoFuture

Creates a future from a value. Read more
§

impl<T> MaybeSend for T
where T: Send + ?Sized,

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
§

impl<F, T, E> TryFuture for F
where F: Future<Output = Result<T, E>> + ?Sized,

§

type Ok = T

The type of successful values yielded by this future
§

type Error = E

The type of failures yielded by this future
§

fn try_poll( self: Pin<&mut F>, cx: &mut Context<'_>, ) -> Poll<<F as Future>::Output>

Poll this TryFuture as if it were a Future. Read more
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.