Struct tokio::sync::oneshot::Receiver

source ·
pub struct Receiver<T> { /* private fields */ }
Available on crate feature sync only.
Expand description

Receives a value from the associated Sender.

A pair of both a Sender and a Receiver are created by the channel function.

This channel has no recv method because the receiver itself implements the Future trait. To receive a value, .await the Receiver object directly.

The poll method on the Future trait is allowed to spuriously return Poll::Pending even if the message has been sent. If such a spurious failure happens, then the caller will be woken when the spurious failure has been resolved so that the caller can attempt to receive the message again. Note that receiving such a wakeup does not guarantee that the next call will succeed — it could fail with another spurious failure. (A spurious failure does not mean that the message is lost. It is just delayed.)

Examples

use tokio::sync::oneshot;

#[tokio::main]
async fn main() {
    let (tx, rx) = oneshot::channel();

    tokio::spawn(async move {
        if let Err(_) = tx.send(3) {
            println!("the receiver dropped");
        }
    });

    match rx.await {
        Ok(v) => println!("got = {:?}", v),
        Err(_) => println!("the sender dropped"),
    }
}

If the sender is dropped without sending, the receiver will fail with error::RecvError:

use tokio::sync::oneshot;

#[tokio::main]
async fn main() {
    let (tx, rx) = oneshot::channel::<u32>();

    tokio::spawn(async move {
        drop(tx);
    });

    match rx.await {
        Ok(_) => panic!("This doesn't happen"),
        Err(_) => println!("the sender dropped"),
    }
}

To use a Receiver in a tokio::select! loop, add &mut in front of the channel.

use tokio::sync::oneshot;
use tokio::time::{interval, sleep, Duration};

#[tokio::main]
async fn main() {
    let (send, mut recv) = oneshot::channel();
    let mut interval = interval(Duration::from_millis(100));

    tokio::spawn(async move {
        sleep(Duration::from_secs(1)).await;
        send.send("shut down").unwrap();
    });

    loop {
        tokio::select! {
            _ = interval.tick() => println!("Another 100ms"),
            msg = &mut recv => {
                println!("Got message: {}", msg.unwrap());
                break;
            }
        }
    }
}

Implementations§

Prevents the associated Sender handle from sending a value.

Any send operation which happens after calling close is guaranteed to fail. After calling close, try_recv should be called to receive a value if one was sent before the call to close completed.

This function is useful to perform a graceful shutdown and ensure that a value will not be sent into the channel and never received.

close is no-op if a message is already received or the channel is already closed.

Examples

Prevent a value from being sent

use tokio::sync::oneshot;
use tokio::sync::oneshot::error::TryRecvError;

#[tokio::main]
async fn main() {
    let (tx, mut rx) = oneshot::channel();

    assert!(!tx.is_closed());

    rx.close();

    assert!(tx.is_closed());
    assert!(tx.send("never received").is_err());

    match rx.try_recv() {
        Err(TryRecvError::Closed) => {}
        _ => unreachable!(),
    }
}

Receive a value sent before calling close

use tokio::sync::oneshot;

#[tokio::main]
async fn main() {
    let (tx, mut rx) = oneshot::channel();

    assert!(tx.send("will receive").is_ok());

    rx.close();

    let msg = rx.try_recv().unwrap();
    assert_eq!(msg, "will receive");
}

Attempts to receive a value.

If a pending value exists in the channel, it is returned. If no value has been sent, the current task will not be registered for future notification.

This function is useful to call from outside the context of an asynchronous task.

Note that unlike the poll method, the try_recv method cannot fail spuriously. Any send or close event that happens before this call to try_recv will be correctly returned to the caller.

Return
  • Ok(T) if a value is pending in the channel.
  • Err(TryRecvError::Empty) if no value has been sent yet.
  • Err(TryRecvError::Closed) if the sender has dropped without sending a value, or if the message has already been received.
Examples

try_recv before a value is sent, then after.

use tokio::sync::oneshot;
use tokio::sync::oneshot::error::TryRecvError;

#[tokio::main]
async fn main() {
    let (tx, mut rx) = oneshot::channel();

    match rx.try_recv() {
        // The channel is currently empty
        Err(TryRecvError::Empty) => {}
        _ => unreachable!(),
    }

    // Send a value
    tx.send("hello").unwrap();

    match rx.try_recv() {
        Ok(value) => assert_eq!(value, "hello"),
        _ => unreachable!(),
    }
}

try_recv when the sender dropped before sending a value

use tokio::sync::oneshot;
use tokio::sync::oneshot::error::TryRecvError;

#[tokio::main]
async fn main() {
    let (tx, mut rx) = oneshot::channel::<()>();

    drop(tx);

    match rx.try_recv() {
        // The channel will never receive a value.
        Err(TryRecvError::Closed) => {}
        _ => unreachable!(),
    }
}

Blocking receive to call outside of asynchronous contexts.

Panics

This function panics if called within an asynchronous execution context.

Examples
use std::thread;
use tokio::sync::oneshot;

#[tokio::main]
async fn main() {
    let (tx, rx) = oneshot::channel::<u8>();

    let sync_code = thread::spawn(move || {
        assert_eq!(Ok(10), rx.blocking_recv());
    });

    let _ = tx.send(10);
    sync_code.join().unwrap();
}

Trait Implementations§

Formats the value using the given formatter. Read more
Executes the destructor for this type. Read more
The type of value produced on completion.
Attempt 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§

Blanket Implementations§

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Instruments this type with the current Span, returning an Instrumented wrapper. Read more

Calls U::from(self).

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

The output that the future will produce on completion.
Which kind of future are we turning this into?
Creates a future from a value. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more