diff --git a/Cargo.lock b/Cargo.lock index 295d1e57c..4d92b1549 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1479,7 +1479,6 @@ dependencies = [ "blake2-rfc", "byteorder", "chrono", - "crossbeam-utils", "data-encoding", "ed25519-dalek", "failure", @@ -1493,6 +1492,7 @@ dependencies = [ "hyper-rustls", "hyper-socks2-mw", "hyper-timeout", + "lazy_static", "log", "rand 0.6.5", "regex", diff --git a/impls/Cargo.toml b/impls/Cargo.toml index 71c8f3297..d99960057 100644 --- a/impls/Cargo.toml +++ b/impls/Cargo.toml @@ -23,7 +23,7 @@ ring = "0.16" tokio = { version = "0.2", features = ["full"] } uuid = { version = "0.8", features = ["serde", "v4"] } chrono = { version = "0.4.11", features = ["serde"] } -crossbeam-utils = "0.7" +lazy_static = "1.4" #http client (copied from grin) http = "0.2" diff --git a/impls/src/client_utils/client.rs b/impls/src/client_utils/client.rs index 76947c263..f2566f62c 100644 --- a/impls/src/client_utils/client.rs +++ b/impls/src/client_utils/client.rs @@ -15,19 +15,35 @@ //! High level JSON/HTTP client API use crate::util::to_base64; -use crossbeam_utils::thread::scope; use failure::{Backtrace, Context, Fail, ResultExt}; use hyper::body; use hyper::header::{ACCEPT, AUTHORIZATION, CONTENT_TYPE, USER_AGENT}; use hyper::{self, Body, Client as HyperClient, Request, Uri}; use hyper_rustls; use hyper_timeout::TimeoutConnector; +use lazy_static::lazy_static; use serde::{Deserialize, Serialize}; use serde_json; use std::fmt::{self, Display}; use std::net::SocketAddr; +use std::sync::{Arc, Mutex}; use std::time::Duration; -use tokio::runtime::Builder; +use tokio::runtime::{Builder, Runtime}; + +// Global Tokio runtime. +// Needs a `Mutex` because `Runtime::block_on` requires mutable access. +// Tokio v0.3 requires immutable self, but we are waiting on upstream +// updates before we can upgrade. +// See: https://github.com/seanmonstar/reqwest/pull/1076 +lazy_static! { + pub static ref RUNTIME: Arc> = Arc::new(Mutex::new( + Builder::new() + .threaded_scheduler() + .enable_all() + .build() + .unwrap() + )); +} /// Errors that can be returned by an ApiEndpoint implementation. #[derive(Debug)] @@ -323,18 +339,9 @@ impl Client { } pub fn send_request(&self, req: Request) -> Result { - let task = self.send_request_async(req); - scope(|s| { - let handle = s.spawn(|_| { - let mut rt = Builder::new() - .basic_scheduler() - .enable_all() - .build() - .context(ErrorKind::Internal("can't create Tokio runtime".to_owned()))?; - rt.block_on(task) - }); - handle.join().unwrap() - }) - .unwrap() + RUNTIME + .lock() + .unwrap() + .block_on(self.send_request_async(req)) } } diff --git a/impls/src/client_utils/mod.rs b/impls/src/client_utils/mod.rs index e4a65b889..f863030d5 100644 --- a/impls/src/client_utils/mod.rs +++ b/impls/src/client_utils/mod.rs @@ -15,4 +15,4 @@ mod client; pub mod json_rpc; -pub use client::{Client, Error as ClientError}; +pub use client::{Client, Error as ClientError, RUNTIME}; diff --git a/impls/src/node_clients/http.rs b/impls/src/node_clients/http.rs index 5c6e226a0..6618c8642 100644 --- a/impls/src/node_clients/http.rs +++ b/impls/src/node_clients/http.rs @@ -17,14 +17,12 @@ use crate::api::{self, LocatedTxKernel, OutputListing, OutputPrintable}; use crate::core::core::{Transaction, TxKernel}; use crate::libwallet::{NodeClient, NodeVersionInfo}; -use crossbeam_utils::thread::scope; use futures::stream::FuturesUnordered; use futures::TryStreamExt; use std::collections::HashMap; use std::env; -use tokio::runtime::Builder; -use crate::client_utils::Client; +use crate::client_utils::{Client, RUNTIME}; use crate::libwallet; use crate::util::secp::pedersen; use crate::util::ToHex; @@ -251,19 +249,7 @@ impl NodeClient for HTTPNodeClient { task.try_collect().await }; - let res = scope(|s| { - let handle = s.spawn(|_| { - let mut rt = Builder::new() - .threaded_scheduler() - .enable_all() - .build() - .unwrap(); - let res: Result, _> = rt.block_on(task); - res - }); - handle.join().unwrap() - }) - .unwrap(); + let res: Result, _> = RUNTIME.lock().unwrap().block_on(task); let results: Vec = match res { Ok(resps) => {