From 44f45bd6d4b6b911fa7427bdbe8598bbc5122e95 Mon Sep 17 00:00:00 2001 From: Alice Ryhl Date: Wed, 10 Jun 2020 10:56:28 +0200 Subject: [PATCH 1/3] sync: elaborate on unbounded send not being async --- tokio/src/sync/mpsc/unbounded.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tokio/src/sync/mpsc/unbounded.rs b/tokio/src/sync/mpsc/unbounded.rs index ba543fe4c87..5054323beba 100644 --- a/tokio/src/sync/mpsc/unbounded.rs +++ b/tokio/src/sync/mpsc/unbounded.rs @@ -167,6 +167,10 @@ impl UnboundedSender { /// being called or the [`UnboundedReceiver`] having been dropped, /// the function returns an error. The error includes the value passed to `send`. /// + /// This method is not marked async because sending a message to an unbounded channel + /// never requires any form of waiting. Because of this, the `send` method can be + /// used in both synchronous and asynchronous code without problems. + /// /// [`close`]: UnboundedReceiver::close /// [`UnboundedReceiver`]: UnboundedReceiver pub fn send(&self, message: T) -> Result<(), SendError> { From 2dae08bb3a86ec2914f04b0a763e77cd5eb1b0da Mon Sep 17 00:00:00 2001 From: Alice Ryhl Date: Wed, 10 Jun 2020 23:29:24 +0200 Subject: [PATCH 2/3] more unbounded channel doc --- tokio/src/sync/mpsc/mod.rs | 31 +++++++++++++++++++++++++++++-- tokio/src/sync/mpsc/unbounded.rs | 8 ++++---- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/tokio/src/sync/mpsc/mod.rs b/tokio/src/sync/mpsc/mod.rs index d816557f91b..b2d516a1d17 100644 --- a/tokio/src/sync/mpsc/mod.rs +++ b/tokio/src/sync/mpsc/mod.rs @@ -10,8 +10,13 @@ //! is rejected and the task will be notified when additional capacity is //! available. In other words, the channel provides backpressure. //! -//! Unbounded channels are also available using the `unbounded_channel` -//! constructor. +//! This module provides two variants of the channel: A bounded and an unbounded +//! variant. The bounded variant has a limit on the number of messages that the +//! channel can store, and if this limit is reached, trying to send another +//! message will sleep until a message is received from the channel. An unbounded +//! channel has an infinite capacity, so the `send` method never does any kind of +//! sleeping. This makes the [`UnboundedSender`] usable from both synchronous and +//! asynchronous code. //! //! # Disconnection //! @@ -32,8 +37,30 @@ //! consumes the channel to completion, at which point the receiver can be //! dropped. //! +//! # Communicating between sync and async code +//! +//! When you want to communicate between synchronous and asynchronous code, there +//! are two situations to consider: +//! +//! **Bounded channel**: If you need a bounded channel, you should use a bounded +//! Tokio mpsc channel for both directions of communication. To call the async +//! [`send`][bounded-send] or [`recv`][bounded-recv] methods in sync code, you +//! should use [`Handle::block_on`]. +//! +//! **Unbounded channel**: You should use the kind of channel that matches where +//! the receiver is. So for sending a message _from async to sync_, you should +//! use [the standard library unbounded channel][std-unbounded] or +//! [crossbeam][crossbeam-unbounded]. Similarly, for sending a message _from sync +//! to async_, you should use a Tokio mpsc channel. +//! //! [`Sender`]: crate::sync::mpsc::Sender //! [`Receiver`]: crate::sync::mpsc::Receiver +//! [bounded-send]: crate::sync::mpsc::Sender::send() +//! [bounded-recv]: crate::sync::mpsc::Receiver::recv() +//! [`UnboundedSender`]: crate::sync::mpsc::UnboundedSender +//! [`Handle::block_on`]: crate::runtime::Handle::block_on() +//! [std-unbounded]: std::sync::mpsc::channel +//! [crossbeam-unbounded]: https://docs.rs/crossbeam/*/crossbeam/channel/fn.unbounded.html pub(super) mod block; diff --git a/tokio/src/sync/mpsc/unbounded.rs b/tokio/src/sync/mpsc/unbounded.rs index 5054323beba..1b2288ab08c 100644 --- a/tokio/src/sync/mpsc/unbounded.rs +++ b/tokio/src/sync/mpsc/unbounded.rs @@ -163,14 +163,14 @@ impl UnboundedSender { /// Attempts to send a message on this `UnboundedSender` without blocking. /// - /// If the receive half of the channel is closed, either due to [`close`] - /// being called or the [`UnboundedReceiver`] having been dropped, - /// the function returns an error. The error includes the value passed to `send`. - /// /// This method is not marked async because sending a message to an unbounded channel /// never requires any form of waiting. Because of this, the `send` method can be /// used in both synchronous and asynchronous code without problems. /// + /// If the receive half of the channel is closed, either due to [`close`] + /// being called or the [`UnboundedReceiver`] having been dropped, this + /// function returns an error. The error includes the value passed to `send`. + /// /// [`close`]: UnboundedReceiver::close /// [`UnboundedReceiver`]: UnboundedReceiver pub fn send(&self, message: T) -> Result<(), SendError> { From 8e5c9b66c9ad42de610075a6d6a9be28a851c117 Mon Sep 17 00:00:00 2001 From: Alice Ryhl Date: Thu, 11 Jun 2020 10:47:38 +0200 Subject: [PATCH 3/3] more channel doc --- tokio/src/sync/mpsc/mod.rs | 8 +++++--- tokio/src/sync/oneshot.rs | 7 +++++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/tokio/src/sync/mpsc/mod.rs b/tokio/src/sync/mpsc/mod.rs index b2d516a1d17..52e234a5c2a 100644 --- a/tokio/src/sync/mpsc/mod.rs +++ b/tokio/src/sync/mpsc/mod.rs @@ -43,15 +43,17 @@ //! are two situations to consider: //! //! **Bounded channel**: If you need a bounded channel, you should use a bounded -//! Tokio mpsc channel for both directions of communication. To call the async +//! Tokio `mpsc` channel for both directions of communication. To call the async //! [`send`][bounded-send] or [`recv`][bounded-recv] methods in sync code, you -//! should use [`Handle::block_on`]. +//! will need to use [`Handle::block_on`], which allow you to execute an async +//! method in synchronous code. This is necessary because a bounded channel may +//! need to wait for additional capacity to become available. //! //! **Unbounded channel**: You should use the kind of channel that matches where //! the receiver is. So for sending a message _from async to sync_, you should //! use [the standard library unbounded channel][std-unbounded] or //! [crossbeam][crossbeam-unbounded]. Similarly, for sending a message _from sync -//! to async_, you should use a Tokio mpsc channel. +//! to async_, you should use an unbounded Tokio `mpsc` channel. //! //! [`Sender`]: crate::sync::mpsc::Sender //! [`Receiver`]: crate::sync::mpsc::Receiver diff --git a/tokio/src/sync/oneshot.rs b/tokio/src/sync/oneshot.rs index 4b033ac3adf..54cd5b76f0a 100644 --- a/tokio/src/sync/oneshot.rs +++ b/tokio/src/sync/oneshot.rs @@ -144,8 +144,11 @@ impl Sender { /// Attempts to send a value on this channel, returning it back if it could /// not be sent. /// - /// The function consumes `self` as only one value may ever be sent on a - /// one-shot channel. + /// This method consumes `self` as only one value may ever be sent on a oneshot + /// channel. It is not marked async because sending a message to an oneshot + /// channel never requires any form of waiting. Because of this, the `send` + /// method can be used in both synchronous and asynchronous code without + /// problems. /// /// A successful send occurs when it is determined that the other end of the /// channel has not hung up already. An unsuccessful send would be one where