From d8e703c4b863b150b47ff16ed4dae762925005c4 Mon Sep 17 00:00:00 2001 From: Scott Piriou Date: Sun, 21 Jun 2020 14:30:56 +0200 Subject: [PATCH 1/8] Fix typo in offchain's docs --- client/offchain/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/offchain/src/lib.rs b/client/offchain/src/lib.rs index a1ea16a72e9f4..7377da2cdb0b7 100644 --- a/client/offchain/src/lib.rs +++ b/client/offchain/src/lib.rs @@ -19,7 +19,7 @@ //! The offchain workers is a special function of the runtime that //! gets executed after block is imported. During execution //! it's able to asynchronously submit extrinsics that will either -//! be propagated to other nodes added to the next block +//! be propagated to other nodes or added to the next block //! produced by the node as unsigned transactions. //! //! Offchain workers can be used for computation-heavy tasks From c23b583bf2e50366efb61618fea0b24ca5ba17ba Mon Sep 17 00:00:00 2001 From: Scott Piriou Date: Sun, 21 Jun 2020 15:29:22 +0200 Subject: [PATCH 2/8] Use Self keyword in AsyncApi::new() --- client/offchain/src/api.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/offchain/src/api.rs b/client/offchain/src/api.rs index a7f4ecbc5825e..d84c869c9bed8 100644 --- a/client/offchain/src/api.rs +++ b/client/offchain/src/api.rs @@ -260,7 +260,7 @@ impl AsyncApi { db: S, network_state: Arc, is_validator: bool, - ) -> (Api, AsyncApi) { + ) -> (Api, Self) { let (http_api, http_worker) = http::http(); let api = Api { @@ -270,7 +270,7 @@ impl AsyncApi { http: http_api, }; - let async_api = AsyncApi { + let async_api = Self { http: Some(http_worker), }; From d8fbf03ae1f5fdf56d6e50774d3a46603504dcd5 Mon Sep 17 00:00:00 2001 From: Scott Piriou Date: Sun, 21 Jun 2020 16:19:59 +0200 Subject: [PATCH 3/8] Move httpclient to be part of OffchainWorkers to optimize block import --- client/offchain/src/api.rs | 3 ++- client/offchain/src/api/http.rs | 9 ++++++--- client/offchain/src/lib.rs | 6 ++++++ 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/client/offchain/src/api.rs b/client/offchain/src/api.rs index d84c869c9bed8..85d31b3482022 100644 --- a/client/offchain/src/api.rs +++ b/client/offchain/src/api.rs @@ -260,8 +260,9 @@ impl AsyncApi { db: S, network_state: Arc, is_validator: bool, + hyper_client: Arc, hyper::Body>>, ) -> (Api, Self) { - let (http_api, http_worker) = http::http(); + let (http_api, http_worker) = http::http(hyper_client); let api = Api { db, diff --git a/client/offchain/src/api/http.rs b/client/offchain/src/api/http.rs index 91a673872fc7c..e71296e15dd62 100644 --- a/client/offchain/src/api/http.rs +++ b/client/offchain/src/api/http.rs @@ -33,9 +33,12 @@ use log::error; use sp_core::offchain::{HttpRequestId, Timestamp, HttpRequestStatus, HttpError}; use std::{convert::TryFrom, fmt, io::Read as _, pin::Pin, task::{Context, Poll}}; use sp_utils::mpsc::{tracing_unbounded, TracingUnboundedSender, TracingUnboundedReceiver}; +use std::sync::Arc; +use hyper::{Client, Body, client}; +use hyper_rustls::HttpsConnector; /// Creates a pair of [`HttpApi`] and [`HttpWorker`]. -pub fn http() -> (HttpApi, HttpWorker) { +pub fn http(hyper_client: Arc, Body>>) -> (HttpApi, HttpWorker) { let (to_worker, from_api) = tracing_unbounded("mpsc_ocw_to_worker"); let (to_api, from_worker) = tracing_unbounded("mpsc_ocw_to_api"); @@ -51,7 +54,7 @@ pub fn http() -> (HttpApi, HttpWorker) { let engine = HttpWorker { to_api, from_api, - http_client: hyper::Client::builder().build(hyper_rustls::HttpsConnector::new()), + http_client: hyper_client, requests: Vec::new(), }; @@ -551,7 +554,7 @@ pub struct HttpWorker { /// Used to receive messages from the `HttpApi`. from_api: TracingUnboundedReceiver, /// The engine that runs HTTP requests. - http_client: hyper::Client, hyper::Body>, + http_client: Arc, Body>>, /// HTTP requests that are being worked on by the engine. requests: Vec<(HttpRequestId, HttpWorkerRequest)>, } diff --git a/client/offchain/src/lib.rs b/client/offchain/src/lib.rs index 7377da2cdb0b7..2562620fefa1f 100644 --- a/client/offchain/src/lib.rs +++ b/client/offchain/src/lib.rs @@ -44,6 +44,8 @@ use sc_network::NetworkStateInfo; use sp_core::{offchain::{self, OffchainStorage}, ExecutionContext, traits::SpawnNamed}; use sp_runtime::{generic::BlockId, traits::{self, Header}}; use futures::{prelude::*, future::ready}; +use hyper_rustls::HttpsConnector; +use hyper::{Client as HyperClient, Body, client}; mod api; @@ -55,16 +57,19 @@ pub struct OffchainWorkers { db: Storage, _block: PhantomData, thread_pool: Mutex, + hyper_client: Arc, Body>>, } impl OffchainWorkers { /// Creates new `OffchainWorkers`. pub fn new(client: Arc, db: Storage) -> Self { + let hyper_client = Arc::new(HyperClient::builder().build(HttpsConnector::new())); Self { client, db, _block: PhantomData, thread_pool: Mutex::new(ThreadPool::new(num_cpus::get())), + hyper_client, } } } @@ -120,6 +125,7 @@ impl OffchainWorkers< self.db.clone(), network_state.clone(), is_validator, + self.hyper_client.clone(), ); debug!("Spawning offchain workers at {:?}", at); let header = header.clone(); From 814c48132dee9c34de2f9e29c96b93e84f0407a2 Mon Sep 17 00:00:00 2001 From: Scott Piriou Date: Sun, 21 Jun 2020 17:27:55 +0200 Subject: [PATCH 4/8] Fix compilation errors for tests --- client/offchain/src/api.rs | 5 +++++ client/offchain/src/api/http.rs | 12 ++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/client/offchain/src/api.rs b/client/offchain/src/api.rs index 85d31b3482022..bd1fcbf88efcd 100644 --- a/client/offchain/src/api.rs +++ b/client/offchain/src/api.rs @@ -292,6 +292,8 @@ mod tests { use std::{convert::{TryFrom, TryInto}, time::SystemTime}; use sc_client_db::offchain::LocalStorage; use sc_network::PeerId; + use hyper_rustls::HttpsConnector; + use hyper::{Client as HyperClient}; struct MockNetworkStateInfo(); @@ -309,11 +311,14 @@ mod tests { let _ = env_logger::try_init(); let db = LocalStorage::new_test(); let mock = Arc::new(MockNetworkStateInfo()); + let hyper_client = Arc::new(HyperClient::builder().build(HttpsConnector::new())); + AsyncApi::new( db, mock, false, + hyper_client, ) } diff --git a/client/offchain/src/api/http.rs b/client/offchain/src/api/http.rs index e71296e15dd62..89be2aefc8299 100644 --- a/client/offchain/src/api/http.rs +++ b/client/offchain/src/api/http.rs @@ -34,11 +34,11 @@ use sp_core::offchain::{HttpRequestId, Timestamp, HttpRequestStatus, HttpError}; use std::{convert::TryFrom, fmt, io::Read as _, pin::Pin, task::{Context, Poll}}; use sp_utils::mpsc::{tracing_unbounded, TracingUnboundedSender, TracingUnboundedReceiver}; use std::sync::Arc; -use hyper::{Client, Body, client}; +use hyper::{Client as HyperClient, Body, client}; use hyper_rustls::HttpsConnector; /// Creates a pair of [`HttpApi`] and [`HttpWorker`]. -pub fn http(hyper_client: Arc, Body>>) -> (HttpApi, HttpWorker) { +pub fn http(hyper_client: Arc, Body>>) -> (HttpApi, HttpWorker) { let (to_worker, from_api) = tracing_unbounded("mpsc_ocw_to_worker"); let (to_api, from_worker) = tracing_unbounded("mpsc_ocw_to_api"); @@ -554,7 +554,7 @@ pub struct HttpWorker { /// Used to receive messages from the `HttpApi`. from_api: TracingUnboundedReceiver, /// The engine that runs HTTP requests. - http_client: Arc, Body>>, + http_client: Arc, Body>>, /// HTTP requests that are being worked on by the engine. requests: Vec<(HttpRequestId, HttpWorkerRequest)>, } @@ -691,6 +691,9 @@ mod tests { use super::http; use sp_core::offchain::{HttpError, HttpRequestId, HttpRequestStatus, Duration}; use futures::future; + use std::sync::Arc; + use hyper::{Client as HyperClient}; + use hyper_rustls::HttpsConnector; // Returns an `HttpApi` whose worker is ran in the background, and a `SocketAddr` to an HTTP // server that runs in the background as well. @@ -702,7 +705,8 @@ mod tests { // not be enough). fdlimit::raise_fd_limit(); - let (api, worker) = http(); + let hyper_client = Arc::new(HyperClient::builder().build(HttpsConnector::new())); + let (api, worker) = http(hyper_client.clone()); let (addr_tx, addr_rx) = std::sync::mpsc::channel(); std::thread::spawn(move || { From cf434c811262004efbf91c1510b12021e70071f7 Mon Sep 17 00:00:00 2001 From: Scott Piriou Date: Mon, 22 Jun 2020 16:29:17 +0200 Subject: [PATCH 5/8] Add wrapper struct for HyperClient --- client/offchain/src/api.rs | 3 ++- client/offchain/src/api/http.rs | 14 ++++++++++++-- client/offchain/src/api/http_dummy.rs | 12 +++++++++++- client/offchain/src/lib.rs | 11 +++++------ 4 files changed, 30 insertions(+), 10 deletions(-) diff --git a/client/offchain/src/api.rs b/client/offchain/src/api.rs index bd1fcbf88efcd..b4c414eb4748e 100644 --- a/client/offchain/src/api.rs +++ b/client/offchain/src/api.rs @@ -31,6 +31,7 @@ use sp_core::offchain::{ OpaqueNetworkState, OpaquePeerId, OpaqueMultiaddr, StorageKind, }; pub use sp_offchain::STORAGE_PREFIX; +pub use http::SharedClient; #[cfg(not(target_os = "unknown"))] mod http; @@ -260,7 +261,7 @@ impl AsyncApi { db: S, network_state: Arc, is_validator: bool, - hyper_client: Arc, hyper::Body>>, + hyper_client: SharedClient, ) -> (Api, Self) { let (http_api, http_worker) = http::http(hyper_client); diff --git a/client/offchain/src/api/http.rs b/client/offchain/src/api/http.rs index 89be2aefc8299..7860a95c2142a 100644 --- a/client/offchain/src/api/http.rs +++ b/client/offchain/src/api/http.rs @@ -37,8 +37,18 @@ use std::sync::Arc; use hyper::{Client as HyperClient, Body, client}; use hyper_rustls::HttpsConnector; +/// Wrapper struct used for keeping the hyper_rustls client running. +#[derive(Clone)] +pub struct SharedClient(Arc, Body>>); + +impl SharedClient { + pub fn new() -> Self { + Self(Arc::new(HyperClient::builder().build(HttpsConnector::new()))) + } +} + /// Creates a pair of [`HttpApi`] and [`HttpWorker`]. -pub fn http(hyper_client: Arc, Body>>) -> (HttpApi, HttpWorker) { +pub fn http(shared_client: SharedClient) -> (HttpApi, HttpWorker) { let (to_worker, from_api) = tracing_unbounded("mpsc_ocw_to_worker"); let (to_api, from_worker) = tracing_unbounded("mpsc_ocw_to_api"); @@ -54,7 +64,7 @@ pub fn http(hyper_client: Arc, let engine = HttpWorker { to_api, from_api, - http_client: hyper_client, + http_client: shared_client.0, requests: Vec::new(), }; diff --git a/client/offchain/src/api/http_dummy.rs b/client/offchain/src/api/http_dummy.rs index 5ff77a1068312..1c83325c93b20 100644 --- a/client/offchain/src/api/http_dummy.rs +++ b/client/offchain/src/api/http_dummy.rs @@ -19,8 +19,18 @@ use sp_core::offchain::{HttpRequestId, Timestamp, HttpRequestStatus, HttpError}; use std::{future::Future, pin::Pin, task::Context, task::Poll}; +/// Wrapper struct (wrapping nothing in case of http_dummy) used for keeping the hyper_rustls client running. +#[derive(Clone)] +pub struct SharedClient; + +impl SharedClient { + pub fn new() -> Self { + Self + } +} + /// Creates a pair of [`HttpApi`] and [`HttpWorker`]. -pub fn http() -> (HttpApi, HttpWorker) { +pub fn http(_: SharedClient) -> (HttpApi, HttpWorker) { (HttpApi, HttpWorker) } diff --git a/client/offchain/src/lib.rs b/client/offchain/src/lib.rs index 2562620fefa1f..7c90065746aa3 100644 --- a/client/offchain/src/lib.rs +++ b/client/offchain/src/lib.rs @@ -44,10 +44,9 @@ use sc_network::NetworkStateInfo; use sp_core::{offchain::{self, OffchainStorage}, ExecutionContext, traits::SpawnNamed}; use sp_runtime::{generic::BlockId, traits::{self, Header}}; use futures::{prelude::*, future::ready}; -use hyper_rustls::HttpsConnector; -use hyper::{Client as HyperClient, Body, client}; mod api; +use api::SharedClient; pub use sp_offchain::{OffchainWorkerApi, STORAGE_PREFIX}; @@ -57,19 +56,19 @@ pub struct OffchainWorkers { db: Storage, _block: PhantomData, thread_pool: Mutex, - hyper_client: Arc, Body>>, + shared_client: SharedClient, } impl OffchainWorkers { /// Creates new `OffchainWorkers`. pub fn new(client: Arc, db: Storage) -> Self { - let hyper_client = Arc::new(HyperClient::builder().build(HttpsConnector::new())); + let shared_client = SharedClient::new(); Self { client, db, _block: PhantomData, thread_pool: Mutex::new(ThreadPool::new(num_cpus::get())), - hyper_client, + shared_client, } } } @@ -125,7 +124,7 @@ impl OffchainWorkers< self.db.clone(), network_state.clone(), is_validator, - self.hyper_client.clone(), + self.shared_client.clone(), ); debug!("Spawning offchain workers at {:?}", at); let header = header.clone(); From 7af97498a2383b5d7405e27823db8fd97245da41 Mon Sep 17 00:00:00 2001 From: Scott Piriou Date: Mon, 22 Jun 2020 16:45:48 +0200 Subject: [PATCH 6/8] Use lazy_static share SharedClient amongst OffchainWorkers. Remove the need to raise the fd limit --- Cargo.lock | 1 + client/offchain/Cargo.toml | 1 + client/offchain/src/api/http.rs | 6 ------ client/offchain/src/lib.rs | 8 +++++++- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 75976823954a1..4b3c394329f26 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6570,6 +6570,7 @@ dependencies = [ "futures-timer 3.0.2", "hyper 0.13.4", "hyper-rustls", + "lazy_static", "log", "num_cpus", "parity-scale-codec", diff --git a/client/offchain/Cargo.toml b/client/offchain/Cargo.toml index a9cd8c4deabbb..652c85dff2397 100644 --- a/client/offchain/Cargo.toml +++ b/client/offchain/Cargo.toml @@ -30,6 +30,7 @@ sp-runtime = { version = "2.0.0-rc3", path = "../../primitives/runtime" } sp-utils = { version = "2.0.0-rc3", path = "../../primitives/utils" } sc-network = { version = "0.8.0-rc3", path = "../network" } sc-keystore = { version = "2.0.0-rc3", path = "../keystore" } +lazy_static = "1.4.0" [target.'cfg(not(target_os = "unknown"))'.dependencies] hyper = "0.13.2" diff --git a/client/offchain/src/api/http.rs b/client/offchain/src/api/http.rs index 7860a95c2142a..0d71542365d51 100644 --- a/client/offchain/src/api/http.rs +++ b/client/offchain/src/api/http.rs @@ -709,12 +709,6 @@ mod tests { // server that runs in the background as well. macro_rules! build_api_server { () => {{ - // We spawn quite a bit of HTTP servers here due to how async API - // works for offchain workers, so be sure to raise the FD limit - // (particularly useful for macOS where the default soft limit may - // not be enough). - fdlimit::raise_fd_limit(); - let hyper_client = Arc::new(HyperClient::builder().build(HttpsConnector::new())); let (api, worker) = http(hyper_client.clone()); diff --git a/client/offchain/src/lib.rs b/client/offchain/src/lib.rs index 7c90065746aa3..3ee29c88a5ac4 100644 --- a/client/offchain/src/lib.rs +++ b/client/offchain/src/lib.rs @@ -44,12 +44,18 @@ use sc_network::NetworkStateInfo; use sp_core::{offchain::{self, OffchainStorage}, ExecutionContext, traits::SpawnNamed}; use sp_runtime::{generic::BlockId, traits::{self, Header}}; use futures::{prelude::*, future::ready}; +use lazy_static::lazy_static; mod api; use api::SharedClient; pub use sp_offchain::{OffchainWorkerApi, STORAGE_PREFIX}; +lazy_static! { + // Using lazy_static to have the `SharedClient` shared amongst the different OffchainWorkers. + static ref SHARED_CLIENT: SharedClient = SharedClient::new(); +} + /// An offchain workers manager. pub struct OffchainWorkers { client: Arc, @@ -62,7 +68,7 @@ pub struct OffchainWorkers { impl OffchainWorkers { /// Creates new `OffchainWorkers`. pub fn new(client: Arc, db: Storage) -> Self { - let shared_client = SharedClient::new(); + let shared_client = SHARED_CLIENT.clone(); Self { client, db, From fc822c4ae132e99b42314dd3ac1fcaebdea83e81 Mon Sep 17 00:00:00 2001 From: Scott Piriou Date: Tue, 23 Jun 2020 10:34:42 +0200 Subject: [PATCH 7/8] Revert "Use lazy_static share SharedClient amongst OffchainWorkers. Remove the need to raise the fd limit" This reverts commit 7af97498a2383b5d7405e27823db8fd97245da41. --- Cargo.lock | 1 - client/offchain/Cargo.toml | 1 - client/offchain/src/api/http.rs | 6 ++++++ client/offchain/src/lib.rs | 8 +------- 4 files changed, 7 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4b3c394329f26..75976823954a1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6570,7 +6570,6 @@ dependencies = [ "futures-timer 3.0.2", "hyper 0.13.4", "hyper-rustls", - "lazy_static", "log", "num_cpus", "parity-scale-codec", diff --git a/client/offchain/Cargo.toml b/client/offchain/Cargo.toml index 652c85dff2397..a9cd8c4deabbb 100644 --- a/client/offchain/Cargo.toml +++ b/client/offchain/Cargo.toml @@ -30,7 +30,6 @@ sp-runtime = { version = "2.0.0-rc3", path = "../../primitives/runtime" } sp-utils = { version = "2.0.0-rc3", path = "../../primitives/utils" } sc-network = { version = "0.8.0-rc3", path = "../network" } sc-keystore = { version = "2.0.0-rc3", path = "../keystore" } -lazy_static = "1.4.0" [target.'cfg(not(target_os = "unknown"))'.dependencies] hyper = "0.13.2" diff --git a/client/offchain/src/api/http.rs b/client/offchain/src/api/http.rs index 0d71542365d51..7860a95c2142a 100644 --- a/client/offchain/src/api/http.rs +++ b/client/offchain/src/api/http.rs @@ -709,6 +709,12 @@ mod tests { // server that runs in the background as well. macro_rules! build_api_server { () => {{ + // We spawn quite a bit of HTTP servers here due to how async API + // works for offchain workers, so be sure to raise the FD limit + // (particularly useful for macOS where the default soft limit may + // not be enough). + fdlimit::raise_fd_limit(); + let hyper_client = Arc::new(HyperClient::builder().build(HttpsConnector::new())); let (api, worker) = http(hyper_client.clone()); diff --git a/client/offchain/src/lib.rs b/client/offchain/src/lib.rs index 3ee29c88a5ac4..7c90065746aa3 100644 --- a/client/offchain/src/lib.rs +++ b/client/offchain/src/lib.rs @@ -44,18 +44,12 @@ use sc_network::NetworkStateInfo; use sp_core::{offchain::{self, OffchainStorage}, ExecutionContext, traits::SpawnNamed}; use sp_runtime::{generic::BlockId, traits::{self, Header}}; use futures::{prelude::*, future::ready}; -use lazy_static::lazy_static; mod api; use api::SharedClient; pub use sp_offchain::{OffchainWorkerApi, STORAGE_PREFIX}; -lazy_static! { - // Using lazy_static to have the `SharedClient` shared amongst the different OffchainWorkers. - static ref SHARED_CLIENT: SharedClient = SharedClient::new(); -} - /// An offchain workers manager. pub struct OffchainWorkers { client: Arc, @@ -68,7 +62,7 @@ pub struct OffchainWorkers { impl OffchainWorkers { /// Creates new `OffchainWorkers`. pub fn new(client: Arc, db: Storage) -> Self { - let shared_client = SHARED_CLIENT.clone(); + let shared_client = SharedClient::new(); Self { client, db, From 531353412e581114405fdd9355d344ce930249c6 Mon Sep 17 00:00:00 2001 From: Scott Piriou Date: Tue, 23 Jun 2020 11:01:02 +0200 Subject: [PATCH 8/8] Add lazy_static for tests --- Cargo.lock | 2 +- client/offchain/Cargo.toml | 2 +- client/offchain/src/api.rs | 10 ++++------ client/offchain/src/api/http.rs | 20 +++++++++----------- 4 files changed, 15 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 75976823954a1..2834c3ee4e6e0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6564,12 +6564,12 @@ version = "2.0.0-rc3" dependencies = [ "bytes 0.5.4", "env_logger 0.7.1", - "fdlimit", "fnv", "futures 0.3.4", "futures-timer 3.0.2", "hyper 0.13.4", "hyper-rustls", + "lazy_static", "log", "num_cpus", "parity-scale-codec", diff --git a/client/offchain/Cargo.toml b/client/offchain/Cargo.toml index a9cd8c4deabbb..819d6ac3a52c1 100644 --- a/client/offchain/Cargo.toml +++ b/client/offchain/Cargo.toml @@ -37,12 +37,12 @@ hyper-rustls = "0.20" [dev-dependencies] env_logger = "0.7.0" -fdlimit = "0.1.4" sc-client-db = { version = "0.8.0-rc3", default-features = true, path = "../db/" } sc-transaction-pool = { version = "2.0.0-rc3", path = "../../client/transaction-pool" } sp-transaction-pool = { version = "2.0.0-rc3", path = "../../primitives/transaction-pool" } substrate-test-runtime-client = { version = "2.0.0-rc3", path = "../../test-utils/runtime/client" } tokio = "0.2" +lazy_static = "1.4.0" [features] default = [] diff --git a/client/offchain/src/api.rs b/client/offchain/src/api.rs index b4c414eb4748e..0aa5d4ad788ab 100644 --- a/client/offchain/src/api.rs +++ b/client/offchain/src/api.rs @@ -261,9 +261,9 @@ impl AsyncApi { db: S, network_state: Arc, is_validator: bool, - hyper_client: SharedClient, + shared_client: SharedClient, ) -> (Api, Self) { - let (http_api, http_worker) = http::http(hyper_client); + let (http_api, http_worker) = http::http(shared_client); let api = Api { db, @@ -293,8 +293,6 @@ mod tests { use std::{convert::{TryFrom, TryInto}, time::SystemTime}; use sc_client_db::offchain::LocalStorage; use sc_network::PeerId; - use hyper_rustls::HttpsConnector; - use hyper::{Client as HyperClient}; struct MockNetworkStateInfo(); @@ -312,14 +310,14 @@ mod tests { let _ = env_logger::try_init(); let db = LocalStorage::new_test(); let mock = Arc::new(MockNetworkStateInfo()); - let hyper_client = Arc::new(HyperClient::builder().build(HttpsConnector::new())); + let shared_client = SharedClient::new(); AsyncApi::new( db, mock, false, - hyper_client, + shared_client, ) } diff --git a/client/offchain/src/api/http.rs b/client/offchain/src/api/http.rs index 7860a95c2142a..1f542b7c11e19 100644 --- a/client/offchain/src/api/http.rs +++ b/client/offchain/src/api/http.rs @@ -698,24 +698,22 @@ impl fmt::Debug for HttpWorkerRequest { mod tests { use core::convert::Infallible; use crate::api::timestamp; - use super::http; + use super::{http, SharedClient}; use sp_core::offchain::{HttpError, HttpRequestId, HttpRequestStatus, Duration}; use futures::future; - use std::sync::Arc; - use hyper::{Client as HyperClient}; - use hyper_rustls::HttpsConnector; + use lazy_static::lazy_static; + + // Using lazy_static to avoid spawning lots of different SharedClients, + // as spawning a SharedClient is CPU-intensive and opens lots of fds. + lazy_static! { + static ref SHARED_CLIENT: SharedClient = SharedClient::new(); + } // Returns an `HttpApi` whose worker is ran in the background, and a `SocketAddr` to an HTTP // server that runs in the background as well. macro_rules! build_api_server { () => {{ - // We spawn quite a bit of HTTP servers here due to how async API - // works for offchain workers, so be sure to raise the FD limit - // (particularly useful for macOS where the default soft limit may - // not be enough). - fdlimit::raise_fd_limit(); - - let hyper_client = Arc::new(HyperClient::builder().build(HttpsConnector::new())); + let hyper_client = SHARED_CLIENT.clone(); let (api, worker) = http(hyper_client.clone()); let (addr_tx, addr_rx) = std::sync::mpsc::channel();