diff --git a/Cargo.lock b/Cargo.lock index f14c0935fe9..93d054508d7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3430,6 +3430,7 @@ dependencies = [ "tempfile", "term_size", "textwrap", + "tokio 0.2.21", "toml", "verification", "winapi 0.3.8", diff --git a/Cargo.toml b/Cargo.toml index e79f211df2e..74bf91b4d5d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -81,6 +81,7 @@ stats = { path = "util/stats" } term_size = "0.3" textwrap = "0.11.0" toml = "0.5.6" +tokio = { version = "0.2", features = ["blocking"] } verification = { path = "ethcore/verification" } prometheus = "0.9.0" diff --git a/parity/main.rs b/parity/main.rs index 0c2b98d02ef..d4f9c411ca0 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -28,6 +28,7 @@ extern crate openethereum; extern crate parking_lot; extern crate parity_daemonize; extern crate ansi_term; +extern crate tokio; #[cfg(windows)] extern crate winapi; extern crate ethcore_logger; diff --git a/parity/metrics.rs b/parity/metrics.rs index de0474fa12d..6baf22795f6 100644 --- a/parity/metrics.rs +++ b/parity/metrics.rs @@ -45,32 +45,33 @@ struct State { rpc_apis: Arc, } -fn handle_request(req: Request, state: &Arc>) -> Response { +async fn handle_request(req: Request, state: Arc>) -> Response { let (parts, _body) = req.into_parts(); match (parts.method, parts.uri.path()) { (Method::GET, "/metrics") => { - let start = Instant::now(); - let mut reg = prometheus::Registry::new(); - let state = state.lock(); + tokio::task::spawn_blocking(move || { + let start = Instant::now(); + + let mut reg = prometheus::Registry::new(); + let state = state.lock(); + state.rpc_apis.client.prometheus_metrics(&mut reg); + state.rpc_apis.sync.prometheus_metrics(&mut reg); + let elapsed = start.elapsed(); + let ms = (elapsed.as_secs() as i64)*1000 + (elapsed.subsec_millis() as i64); + prometheus_gauge(&mut reg, "metrics_time", "Time to perform rpc metrics", ms); + + let mut buffer = vec![]; + let encoder = prometheus::TextEncoder::new(); + let metric_families = reg.gather(); + + encoder.encode(&metric_families, &mut buffer).expect("all source of metrics are static; qed"); + let text = String::from_utf8(buffer).expect("metrics encoding is ASCII; qed"); + + Response::new(Body::from(text)) + + }).await.expect("The prometheus collection has panicked") - state.rpc_apis.client.prometheus_metrics(&mut reg); - state.rpc_apis.sync.prometheus_metrics(&mut reg); - - drop(state); - - let elapsed = start.elapsed(); - let ms = (elapsed.as_secs() as i64)*1000 + (elapsed.subsec_millis() as i64); - prometheus_gauge(&mut reg, "metrics_time", "Time to perform rpc metrics", ms); - - let mut buffer = vec![]; - let encoder = prometheus::TextEncoder::new(); - let metric_families = reg.gather(); - - encoder.encode(&metric_families, &mut buffer).expect("all source of metrics are static; qed"); - let text = String::from_utf8(buffer).expect("metrics encoding is ASCII; qed"); - - Response::new(Body::from(text)) }, (_, _) => { let mut res = Response::new(Body::from("not found")); @@ -98,12 +99,12 @@ pub fn start_prometheus_metrics(conf: &MetricsConfiguration, deps: &rpc::Depende let state = Arc::new(Mutex::new(state)); deps.executor.spawn_std( async move { - let make_service = make_service_fn(move |_| { - let state = state.clone(); - async move { - Ok::<_, hyper::Error>(service_fn(move |req| { - let response = handle_request(req,&state); - async move { Ok::<_, hyper::Error>(response) } + let make_service = make_service_fn(move |_| { + let state = state.clone(); + async move { + Ok::<_, hyper::Error>(service_fn(move |req| { + let response = handle_request(req, state.clone()); + async move { Ok::<_, hyper::Error>(response.await) } })) } });