Fix panic when calling certain API endpoints (#589)

* Detect if already in runtime context

* Add comment

Co-authored-by: jaspervdm <j@sper.dev>
This commit is contained in:
Quentin Le Sceller 2021-03-05 13:29:08 -05:00 committed by GitHub
parent 712101bba2
commit 563b456e47
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -28,7 +28,7 @@ use std::fmt::{self, Display};
use std::net::SocketAddr; use std::net::SocketAddr;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use std::time::Duration; use std::time::Duration;
use tokio::runtime::{Builder, Runtime}; use tokio::runtime::{Builder, Handle, Runtime};
// Global Tokio runtime. // Global Tokio runtime.
// Needs a `Mutex` because `Runtime::block_on` requires mutable access. // Needs a `Mutex` because `Runtime::block_on` requires mutable access.
@ -101,6 +101,7 @@ impl From<Context<ErrorKind>> for Error {
} }
} }
#[derive(Clone)]
pub struct Client { pub struct Client {
/// Whether to use socks proxy /// Whether to use socks proxy
pub use_socks: bool, pub use_socks: bool,
@ -339,9 +340,20 @@ impl Client {
} }
pub fn send_request(&self, req: Request<Body>) -> Result<String, Error> { pub fn send_request(&self, req: Request<Body>) -> Result<String, Error> {
RUNTIME // This client is currently used both outside and inside of a tokio runtime
.lock() // context. In the latter case we are not allowed to do a blocking call to
.unwrap() // our global runtime, which unfortunately means we have to spawn a new thread
.block_on(self.send_request_async(req)) 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))
}
} }
} }