Expand description
A one-shot channel is used for sending a single message between
asynchronous tasks. The channel function is used to create a
Sender and Receiver handle pair that form the channel.
The Sender handle is used by the producer to send the value.
The Receiver handle is used by the consumer to receive the value.
Each handle can be used on separate tasks.
Since the send method is not async, it can be used anywhere. This includes
sending between two runtimes, and using it from non-async code.
If the Receiver is closed before receiving a message which has already
been sent, the message will remain in the channel until the receiver is
dropped, at which point the message will be dropped immediately.
§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 oneshot channel 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;
}
}
}
}To use a Sender from a destructor, put it in an Option and call
Option::take.
use tokio::sync::oneshot;
struct SendOnDrop {
sender: Option<oneshot::Sender<&'static str>>,
}
impl Drop for SendOnDrop {
fn drop(&mut self) {
if let Some(sender) = self.sender.take() {
// Using `let _ =` to ignore send errors.
let _ = sender.send("I got dropped!");
}
}
}
#[tokio::main]
async fn main() {
let (send, recv) = oneshot::channel();
let send_on_drop = SendOnDrop { sender: Some(send) };
drop(send_on_drop);
assert_eq!(recv.await, Ok("I got dropped!"));
}Modules§
- error
Oneshoterror types.
Structs§
Functions§
- channel
- Creates a new one-shot channel for sending single values across asynchronous tasks.