From 563b456e47ec51ef9415c67b93f82aa3ac1c5e7b Mon Sep 17 00:00:00 2001 From: Quentin Le Sceller Date: Fri, 5 Mar 2021 13:29:08 -0500 Subject: [PATCH] Fix panic when calling certain API endpoints (#589) * Detect if already in runtime context * Add comment Co-authored-by: jaspervdm --- impls/src/client_utils/client.rs | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/impls/src/client_utils/client.rs b/impls/src/client_utils/client.rs index f2566f62..bf41758a 100644 --- a/impls/src/client_utils/client.rs +++ b/impls/src/client_utils/client.rs @@ -28,7 +28,7 @@ use std::fmt::{self, Display}; use std::net::SocketAddr; use std::sync::{Arc, Mutex}; use std::time::Duration; -use tokio::runtime::{Builder, Runtime}; +use tokio::runtime::{Builder, Handle, Runtime}; // Global Tokio runtime. // Needs a `Mutex` because `Runtime::block_on` requires mutable access. @@ -101,6 +101,7 @@ impl From> for Error { } } +#[derive(Clone)] pub struct Client { /// Whether to use socks proxy pub use_socks: bool, @@ -339,9 +340,20 @@ impl Client { } pub fn send_request(&self, req: Request) -> Result { - RUNTIME - .lock() - .unwrap() - .block_on(self.send_request_async(req)) + // This client is currently used both outside and inside of a tokio runtime + // context. In the latter case we are not allowed to do a blocking call to + // our global runtime, which unfortunately means we have to spawn a new thread + if Handle::try_current().is_ok() { + let rt = RUNTIME.clone(); + let client = self.clone(); + std::thread::spawn(move || rt.lock().unwrap().block_on(client.send_request_async(req))) + .join() + .unwrap() + } else { + RUNTIME + .lock() + .unwrap() + .block_on(self.send_request_async(req)) + } } }