RPC cpu pool (#6023)
* RPC cpu pool. * introduce optional thread pool when processing RPC requests. * Bump jsonrpc. * Removing boxes. * Fix CLI tests.
This commit is contained in:
@@ -180,8 +180,10 @@ usage! {
|
||||
or |c: &Config| otry!(c.rpc).apis.as_ref().map(|vec| vec.join(",")),
|
||||
flag_jsonrpc_hosts: String = "none",
|
||||
or |c: &Config| otry!(c.rpc).hosts.as_ref().map(|vec| vec.join(",")),
|
||||
flag_jsonrpc_threads: Option<usize> = None,
|
||||
or |c: &Config| otry!(c.rpc).threads.map(Some),
|
||||
flag_jsonrpc_server_threads: Option<usize> = None,
|
||||
or |c: &Config| otry!(c.rpc).server_threads.map(Some),
|
||||
flag_jsonrpc_threads: usize = 0usize,
|
||||
or |c: &Config| otry!(c.rpc).processing_threads,
|
||||
|
||||
// WS
|
||||
flag_no_ws: bool = false,
|
||||
@@ -468,7 +470,8 @@ struct Rpc {
|
||||
cors: Option<String>,
|
||||
apis: Option<Vec<String>>,
|
||||
hosts: Option<Vec<String>>,
|
||||
threads: Option<usize>,
|
||||
server_threads: Option<usize>,
|
||||
processing_threads: Option<usize>,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, PartialEq, Deserialize)]
|
||||
@@ -749,7 +752,8 @@ mod tests {
|
||||
flag_jsonrpc_cors: Some("null".into()),
|
||||
flag_jsonrpc_apis: "web3,eth,net,parity,traces,rpc,secretstore".into(),
|
||||
flag_jsonrpc_hosts: "none".into(),
|
||||
flag_jsonrpc_threads: None,
|
||||
flag_jsonrpc_server_threads: None,
|
||||
flag_jsonrpc_threads: 0,
|
||||
|
||||
// WS
|
||||
flag_no_ws: false,
|
||||
@@ -977,7 +981,8 @@ mod tests {
|
||||
cors: None,
|
||||
apis: None,
|
||||
hosts: None,
|
||||
threads: None,
|
||||
server_threads: None,
|
||||
processing_threads: None,
|
||||
}),
|
||||
ipc: Some(Ipc {
|
||||
disable: None,
|
||||
|
||||
@@ -176,9 +176,12 @@ API and Console Options:
|
||||
is additional security against some attack
|
||||
vectors. Special options: "all", "none",
|
||||
(default: {flag_jsonrpc_hosts}).
|
||||
--jsonrpc-threads THREADS Enables experimental faster implementation of JSON-RPC server.
|
||||
--jsonrpc-server-threads NUM Enables experimental faster implementation of JSON-RPC server.
|
||||
Requires Dapps server to be disabled
|
||||
using --no-dapps. (default: {flag_jsonrpc_threads:?})
|
||||
using --no-dapps. (default: {flag_jsonrpc_server_threads:?})
|
||||
--jsonrpc-threads THREADS Turn on additional processing threads in all RPC servers.
|
||||
Setting this to non-zero value allows parallel cpu-heavy queries
|
||||
execution. (default: {flag_jsonrpc_threads})
|
||||
|
||||
--no-ws Disable the WebSockets server. (default: {flag_no_ws})
|
||||
--ws-port PORT Specify the port portion of the WebSockets server
|
||||
|
||||
@@ -137,7 +137,7 @@ impl Configuration {
|
||||
let secretstore_conf = self.secretstore_config()?;
|
||||
let format = self.format()?;
|
||||
|
||||
if self.args.flag_jsonrpc_threads.is_some() && dapps_conf.enabled {
|
||||
if self.args.flag_jsonrpc_server_threads.is_some() && dapps_conf.enabled {
|
||||
dapps_conf.enabled = false;
|
||||
writeln!(&mut stderr(), "Warning: Disabling Dapps server because fast RPC server was enabled.").expect("Error writing to stderr.")
|
||||
}
|
||||
@@ -825,11 +825,12 @@ impl Configuration {
|
||||
},
|
||||
hosts: self.rpc_hosts(),
|
||||
cors: self.rpc_cors(),
|
||||
threads: match self.args.flag_jsonrpc_threads {
|
||||
server_threads: match self.args.flag_jsonrpc_server_threads {
|
||||
Some(threads) if threads > 0 => Some(threads),
|
||||
None => None,
|
||||
_ => return Err("--jsonrpc-threads number needs to be positive.".into()),
|
||||
}
|
||||
_ => return Err("--jsonrpc-server-threads number needs to be positive.".into()),
|
||||
},
|
||||
processing_threads: self.args.flag_jsonrpc_threads,
|
||||
};
|
||||
|
||||
Ok(conf)
|
||||
|
||||
@@ -30,6 +30,7 @@ use rpc_apis::{self, ApiSet};
|
||||
|
||||
pub use parity_rpc::{IpcServer, HttpServer, RequestMiddleware};
|
||||
pub use parity_rpc::ws::Server as WsServer;
|
||||
pub use parity_rpc::informant::CpuPool;
|
||||
|
||||
|
||||
pub const DAPPS_DOMAIN: &'static str = "web3.site";
|
||||
@@ -42,7 +43,8 @@ pub struct HttpConfiguration {
|
||||
pub apis: ApiSet,
|
||||
pub cors: Option<Vec<String>>,
|
||||
pub hosts: Option<Vec<String>>,
|
||||
pub threads: Option<usize>,
|
||||
pub server_threads: Option<usize>,
|
||||
pub processing_threads: usize,
|
||||
}
|
||||
|
||||
impl HttpConfiguration {
|
||||
@@ -63,7 +65,8 @@ impl Default for HttpConfiguration {
|
||||
apis: ApiSet::UnsafeContext,
|
||||
cors: None,
|
||||
hosts: Some(Vec::new()),
|
||||
threads: None,
|
||||
server_threads: None,
|
||||
processing_threads: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -94,7 +97,8 @@ impl From<UiConfiguration> for HttpConfiguration {
|
||||
apis: rpc_apis::ApiSet::SafeContext,
|
||||
cors: None,
|
||||
hosts: conf.hosts,
|
||||
threads: None,
|
||||
server_threads: None,
|
||||
processing_threads: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -176,6 +180,7 @@ pub struct Dependencies<D: rpc_apis::Dependencies> {
|
||||
pub apis: Arc<D>,
|
||||
pub remote: TokioRemote,
|
||||
pub stats: Arc<RpcStats>,
|
||||
pub pool: Option<CpuPool>,
|
||||
}
|
||||
|
||||
pub fn new_ws<D: rpc_apis::Dependencies>(
|
||||
@@ -192,11 +197,12 @@ pub fn new_ws<D: rpc_apis::Dependencies>(
|
||||
let addr = url.parse().map_err(|_| format!("Invalid WebSockets listen host/port given: {}", url))?;
|
||||
|
||||
|
||||
let full_handler = setup_apis(rpc_apis::ApiSet::SafeContext, deps);
|
||||
let pool = deps.pool.clone();
|
||||
let full_handler = setup_apis(rpc_apis::ApiSet::SafeContext, deps, pool.clone());
|
||||
let handler = {
|
||||
let mut handler = MetaIoHandler::with_middleware((
|
||||
rpc::WsDispatcher::new(full_handler),
|
||||
Middleware::new(deps.stats.clone(), deps.apis.activity_notifier())
|
||||
Middleware::new(deps.stats.clone(), deps.apis.activity_notifier(), pool)
|
||||
));
|
||||
let apis = conf.apis.list_apis();
|
||||
deps.apis.extend_with_set(&mut handler, &apis);
|
||||
@@ -252,7 +258,8 @@ pub fn new_http<D: rpc_apis::Dependencies>(
|
||||
let http_address = (conf.interface, conf.port);
|
||||
let url = format!("{}:{}", http_address.0, http_address.1);
|
||||
let addr = url.parse().map_err(|_| format!("Invalid {} listen host/port given: {}", id, url))?;
|
||||
let handler = setup_apis(conf.apis, deps);
|
||||
let pool = deps.pool.clone();
|
||||
let handler = setup_apis(conf.apis, deps, pool);
|
||||
let remote = deps.remote.clone();
|
||||
|
||||
let cors_domains = into_domains(conf.cors);
|
||||
@@ -265,7 +272,7 @@ pub fn new_http<D: rpc_apis::Dependencies>(
|
||||
handler,
|
||||
remote,
|
||||
rpc::RpcExtractor,
|
||||
match (conf.threads, middleware) {
|
||||
match (conf.server_threads, middleware) {
|
||||
(Some(threads), None) => rpc::HttpSettings::Threads(threads),
|
||||
(None, middleware) => rpc::HttpSettings::Dapps(middleware),
|
||||
(Some(_), Some(_)) => {
|
||||
@@ -291,7 +298,8 @@ pub fn new_ipc<D: rpc_apis::Dependencies>(
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let handler = setup_apis(conf.apis, dependencies);
|
||||
let pool = dependencies.pool.clone();
|
||||
let handler = setup_apis(conf.apis, dependencies, pool);
|
||||
let remote = dependencies.remote.clone();
|
||||
match rpc::start_ipc(&conf.socket_addr, handler, remote, rpc::RpcExtractor) {
|
||||
Ok(server) => Ok(Some(server)),
|
||||
@@ -318,11 +326,11 @@ fn with_domain(items: Option<Vec<String>>, domain: &str, addresses: &[Option<(St
|
||||
})
|
||||
}
|
||||
|
||||
fn setup_apis<D>(apis: ApiSet, deps: &Dependencies<D>) -> MetaIoHandler<Metadata, Middleware<D::Notifier>>
|
||||
fn setup_apis<D>(apis: ApiSet, deps: &Dependencies<D>, pool: Option<CpuPool>) -> MetaIoHandler<Metadata, Middleware<D::Notifier>>
|
||||
where D: rpc_apis::Dependencies
|
||||
{
|
||||
let mut handler = MetaIoHandler::with_middleware(
|
||||
Middleware::new(deps.stats.clone(), deps.apis.activity_notifier())
|
||||
Middleware::new(deps.stats.clone(), deps.apis.activity_notifier(), pool)
|
||||
);
|
||||
let apis = apis.list_apis();
|
||||
deps.apis.extend_with_set(&mut handler, &apis);
|
||||
|
||||
@@ -316,6 +316,11 @@ fn execute_light(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) ->
|
||||
apis: deps_for_rpc_apis.clone(),
|
||||
remote: event_loop.raw_remote(),
|
||||
stats: rpc_stats.clone(),
|
||||
pool: if cmd.http_conf.processing_threads > 0 {
|
||||
Some(rpc::CpuPool::new(cmd.http_conf.processing_threads))
|
||||
} else {
|
||||
None
|
||||
},
|
||||
};
|
||||
|
||||
// start rpc servers
|
||||
@@ -663,6 +668,12 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) -> R
|
||||
apis: deps_for_rpc_apis.clone(),
|
||||
remote: event_loop.raw_remote(),
|
||||
stats: rpc_stats.clone(),
|
||||
pool: if cmd.http_conf.processing_threads > 0 {
|
||||
Some(rpc::CpuPool::new(cmd.http_conf.processing_threads))
|
||||
} else {
|
||||
None
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
// start rpc servers
|
||||
|
||||
Reference in New Issue
Block a user