From 9ae11b26fc65f3dab51b312f07256d9e652ab599 Mon Sep 17 00:00:00 2001 From: William Chargin Date: Fri, 5 Feb 2021 11:00:11 -0800 Subject: [PATCH] Document that `blocking` and async do not mix (#1159) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See discussion on #1017. This patch adds documentation to `blocking` at module level and to its `Client::new` and `ClientBuilder::build`, noting that you can’t create or use a blocking client from within an async runtime, and suggesting potential alternatives. Presumably, all the other methods on `Client` also have this property, but hitting the failure mode would require building a `blocking::Client` outside an async runtime and then moving it into a runtime to send requests; seems potentially not worth polluting all the docs. Test Plan: Ran `cargo doc --features blocking` and verified that the links work. wchargin-branch: docs-blocking-no-async wchargin-source: 0eb36352959cd2ca0b19df5836e75230dc619b9d --- src/blocking/client.rs | 8 ++++++++ src/blocking/mod.rs | 7 +++++++ 2 files changed, 15 insertions(+) diff --git a/src/blocking/client.rs b/src/blocking/client.rs index ea0766e54..1c6df26f5 100644 --- a/src/blocking/client.rs +++ b/src/blocking/client.rs @@ -92,6 +92,11 @@ impl ClientBuilder { /// /// This method fails if TLS backend cannot be initialized, or the resolver /// cannot load the system configuration. + /// + /// # Panics + /// + /// This method panics if called from within an async runtime. See docs on + /// [`reqwest::blocking`][crate::blocking] for details. pub fn build(self) -> crate::Result { ClientHandle::new(self).map(|handle| Client { inner: handle }) } @@ -606,6 +611,9 @@ impl Client { /// /// Use `Client::builder()` if you wish to handle the failure as an `Error` /// instead of panicking. + /// + /// This method also panics if called from within an async runtime. See docs + /// on [`reqwest::blocking`][crate::blocking] for details. pub fn new() -> Client { ClientBuilder::new().build().expect("Client::new()") } diff --git a/src/blocking/mod.rs b/src/blocking/mod.rs index 550716d7c..7db601d02 100644 --- a/src/blocking/mod.rs +++ b/src/blocking/mod.rs @@ -3,6 +3,13 @@ //! The blocking `Client` will block the current thread to execute, instead //! of returning futures that need to be executed on a runtime. //! +//! Conversely, the functionality in `reqwest::blocking` must *not* be executed +//! within an async runtime, or it will panic when attempting to block. If +//! calling directly from an async function, consider using an async +//! [`reqwest::Client`][crate::Client] instead. If the immediate context is only +//! synchronous, but a transitive caller is async, consider changing that caller +//! to use [`tokio::task::spawn_blocking`] around the calls that need to block. +//! //! # Optional //! //! This requires the optional `blocking` feature to be enabled.