Handle Grafana server bind errors gracefuly. (#4241)

* Fix error handling for grafana sever start.

* Update client/grafana-data-source/src/server.rs

Co-Authored-By: Pierre Krieger <pierre.krieger1708@gmail.com>
This commit is contained in:
Tomasz Drwięga
2019-11-28 12:16:54 +01:00
committed by Gavin Wood
parent 2f35d7f003
commit f78b83e363
4 changed files with 49 additions and 8 deletions
+1
View File
@@ -1672,6 +1672,7 @@ dependencies = [
"futures-util-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.13.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -7,6 +7,7 @@ authors = ["Parity Technologies <admin@parity.io>"]
edition = "2018"
[dependencies]
log = "0.4.8"
hyper = { version = "0.13.0-alpha.4", default-features = false, features = ["unstable-stream"] }
tokio-io = "0.2.0-alpha.6"
tokio-executor = "0.2.0-alpha.6"
@@ -110,12 +110,50 @@ impl<T> tokio_executor::TypedExecutor<T> for Executor
}
}
/// An error that may occur during server runtime.
#[derive(Debug, derive_more::Display, derive_more::From)]
pub enum RunError {
/// Propagated hyper server error.
Hyper(hyper::Error),
/// Initial bind IO error.
Io(std::io::Error),
}
impl std::error::Error for RunError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match *self {
Self::Hyper(ref e) => Some(e),
Self::Io(ref e) => Some(e),
}
}
}
/// Start the data source server.
#[cfg(not(target_os = "unknown"))]
pub async fn run_server(address: std::net::SocketAddr) -> Result<(), hyper::Error> {
pub async fn run_server(mut address: std::net::SocketAddr) -> Result<(), RunError> {
use async_std::{net, io};
use crate::networking::Incoming;
let listener = async_std::net::TcpListener::bind(&address).await.unwrap();
let listener = loop {
let listener = net::TcpListener::bind(&address).await;
match listener {
Ok(listener) => {
log::info!("Grafana data source server started at {}", address);
break listener
},
Err(err) => match err.kind() {
io::ErrorKind::AddrInUse | io::ErrorKind::PermissionDenied if address.port() != 0 => {
log::warn!(
"Unable to bind grafana data source server to {}. Trying random port.",
address
);
address.set_port(0);
continue;
},
_ => Err(err)?,
}
}
};
let service = make_service_fn(|_| {
async {
@@ -128,11 +166,12 @@ pub async fn run_server(address: std::net::SocketAddr) -> Result<(), hyper::Erro
.serve(service)
.boxed();
let clean = clean_up(Duration::days(1), Duration::weeks(1))
let every = std::time::Duration::from_secs(24 * 3600);
let clean = clean_up(every, Duration::weeks(1))
.boxed();
let result = match select(server, clean).await {
Either::Left((result, _)) => result,
Either::Left((result, _)) => result.map_err(Into::into),
Either::Right(_) => Ok(())
};
@@ -140,14 +179,14 @@ pub async fn run_server(address: std::net::SocketAddr) -> Result<(), hyper::Erro
}
#[cfg(target_os = "unknown")]
pub async fn run_server(_: std::net::SocketAddr) -> Result<(), hyper::Error> {
pub async fn run_server(_: std::net::SocketAddr) -> Result<(), RunError> {
Ok(())
}
/// Periodically remove old metrics.
async fn clean_up(every: Duration, before: Duration) {
async fn clean_up(every: std::time::Duration, before: Duration) {
loop {
Delay::new(every.to_std().unwrap()).await;
Delay::new(every).await;
let oldest_allowed = (Utc::now() - before).timestamp_millis();
+1 -1
View File
@@ -524,7 +524,7 @@ fn start_rpc_servers<C, G, E, H: FnMut() -> rpc_servers::RpcHandler<rpc::Metadat
.or_else(|e| match e.kind() {
io::ErrorKind::AddrInUse |
io::ErrorKind::PermissionDenied => {
warn!("Unable to bind server to {}. Trying random port.", address);
warn!("Unable to bind RPC server to {}. Trying random port.", address);
address.set_port(0);
start(&address)
},