This repository has been archived by the owner on Nov 6, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Expose health status over RPC #6274
Merged
Merged
Changes from 10 commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
deb4893
Node-health to a separate crate.
tomusdrw 22bf328
Initialize node_health outside of dapps.
tomusdrw 7ad3de0
Expose health over RPC.
tomusdrw 1bd92c5
Bring back 412 and fix JS.
tomusdrw 30d77a4
Add health to workspace and tests.
tomusdrw bf64e63
Fix compilation without default features.
tomusdrw c70c4f8
Fix borked merge.
tomusdrw 03ed8e9
Merge branch 'master' into health-rpc2
tomusdrw 8d1a60b
Revert to generics to avoid virtual calls.
tomusdrw 182d528
Merge branch 'master' into health-rpc2
tomusdrw 7ed613f
Fix node-health tests.
tomusdrw 2aedc73
Add missing trailing comma.
tomusdrw 8fa178a
Merge branch 'master' into health-rpc2
tomusdrw File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
[package] | ||
name = "node-health" | ||
description = "Node's health status" | ||
version = "0.1.0" | ||
license = "GPL-3.0" | ||
authors = ["Parity Technologies <admin@parity.io>"] | ||
|
||
[dependencies] | ||
futures = "0.1" | ||
futures-cpupool = "0.1" | ||
log = "0.3" | ||
ntp = "0.2.0" | ||
parking_lot = "0.4" | ||
serde = "1.0" | ||
serde_derive = "1.0" | ||
time = "0.1.35" | ||
|
||
parity-reactor = { path = "../../util/reactor" } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
// Copyright 2015-2017 Parity Technologies (UK) Ltd. | ||
// This file is part of Parity. | ||
|
||
// Parity is free software: you can redistribute it and/or modify | ||
// it under the terms of the GNU General Public License as published by | ||
// the Free Software Foundation, either version 3 of the License, or | ||
// (at your option) any later version. | ||
|
||
// Parity is distributed in the hope that it will be useful, | ||
// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
// GNU General Public License for more details. | ||
|
||
// You should have received a copy of the GNU General Public License | ||
// along with Parity. If not, see <http://www.gnu.org/licenses/>. | ||
|
||
//! Reporting node's health. | ||
|
||
use std::sync::Arc; | ||
use std::time; | ||
use futures::{Future, BoxFuture}; | ||
use futures::sync::oneshot; | ||
use types::{HealthInfo, HealthStatus, Health}; | ||
use time::{TimeChecker, MAX_DRIFT}; | ||
use parity_reactor::Remote; | ||
use parking_lot::Mutex; | ||
use {SyncStatus}; | ||
|
||
const TIMEOUT_SECS: u64 = 5; | ||
const PROOF: &str = "Only one closure is invoked."; | ||
|
||
/// A struct enabling you to query for node's health. | ||
#[derive(Debug, Clone)] | ||
pub struct NodeHealth { | ||
sync_status: Arc<SyncStatus>, | ||
time: TimeChecker, | ||
remote: Remote, | ||
} | ||
|
||
impl NodeHealth { | ||
/// Creates new `NodeHealth`. | ||
pub fn new(sync_status: Arc<SyncStatus>, time: TimeChecker, remote: Remote) -> Self { | ||
NodeHealth { sync_status, time, remote, } | ||
} | ||
|
||
/// Query latest health report. | ||
pub fn health(&self) -> BoxFuture<Health, ()> { | ||
trace!(target: "dapps", "Checking node health."); | ||
// Check timediff | ||
let sync_status = self.sync_status.clone(); | ||
let time = self.time.time_drift(); | ||
let (tx, rx) = oneshot::channel(); | ||
let tx = Arc::new(Mutex::new(Some(tx))); | ||
let tx2 = tx.clone(); | ||
self.remote.spawn_with_timeout( | ||
move || time.then(move |result| { | ||
let _ = tx.lock().take().expect(PROOF).send(Ok(result)); | ||
Ok(()) | ||
}), | ||
time::Duration::from_secs(TIMEOUT_SECS), | ||
move || { | ||
let _ = tx2.lock().take().expect(PROOF).send(Err(())); | ||
}, | ||
); | ||
|
||
rx.map_err(|err| { | ||
warn!(target: "dapps", "Health request cancelled: {:?}", err); | ||
}).and_then(move |time| { | ||
// Check peers | ||
let peers = { | ||
let (connected, max) = sync_status.peers(); | ||
let (status, message) = match connected { | ||
0 => { | ||
(HealthStatus::Bad, "You are not connected to any peers. There is most likely some network issue. Fix connectivity.".into()) | ||
}, | ||
1 => (HealthStatus::NeedsAttention, "You are connected to only one peer. Your node might not be reliable. Check your network connection.".into()), | ||
_ => (HealthStatus::Ok, "".into()), | ||
}; | ||
HealthInfo { status, message, details: (connected, max) } | ||
}; | ||
|
||
// Check sync | ||
let sync = { | ||
let is_syncing = sync_status.is_major_importing(); | ||
let (status, message) = if is_syncing { | ||
(HealthStatus::NeedsAttention, "Your node is still syncing, the values you see might be outdated. Wait until it's fully synced.".into()) | ||
} else { | ||
(HealthStatus::Ok, "".into()) | ||
}; | ||
HealthInfo { status, message, details: is_syncing } | ||
}; | ||
|
||
// Check time | ||
let time = { | ||
let (status, message, details) = match time { | ||
Ok(Ok(diff)) if diff < MAX_DRIFT && diff > -MAX_DRIFT => { | ||
(HealthStatus::Ok, "".into(), diff) | ||
}, | ||
Ok(Ok(diff)) => { | ||
(HealthStatus::Bad, format!( | ||
"Your clock is not in sync. Detected difference is too big for the protocol to work: {}ms. Synchronize your clock.", | ||
diff, | ||
), diff) | ||
}, | ||
Ok(Err(err)) => { | ||
(HealthStatus::NeedsAttention, format!( | ||
"Unable to reach time API: {}. Make sure that your clock is synchronized.", | ||
err, | ||
), 0) | ||
}, | ||
Err(_) => { | ||
(HealthStatus::NeedsAttention, "Time API request timed out. Make sure that the clock is synchronized.".into(), 0) | ||
}, | ||
}; | ||
|
||
HealthInfo { status, message, details, } | ||
}; | ||
|
||
Ok(Health { peers, sync, time}) | ||
}).boxed() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
// Copyright 2015-2017 Parity Technologies (UK) Ltd. | ||
// This file is part of Parity. | ||
|
||
// Parity is free software: you can redistribute it and/or modify | ||
// it under the terms of the GNU General Public License as published by | ||
// the Free Software Foundation, either version 3 of the License, or | ||
// (at your option) any later version. | ||
|
||
// Parity is distributed in the hope that it will be useful, | ||
// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
// GNU General Public License for more details. | ||
|
||
// You should have received a copy of the GNU General Public License | ||
// along with Parity. If not, see <http://www.gnu.org/licenses/>. | ||
|
||
//! Node Health status reporting. | ||
|
||
#![warn(missing_docs)] | ||
|
||
extern crate futures; | ||
extern crate futures_cpupool; | ||
extern crate ntp; | ||
extern crate time as time_crate; | ||
extern crate parity_reactor; | ||
extern crate parking_lot; | ||
|
||
#[macro_use] | ||
extern crate log; | ||
#[macro_use] | ||
extern crate serde_derive; | ||
|
||
mod health; | ||
mod time; | ||
mod types; | ||
|
||
pub use futures_cpupool::CpuPool; | ||
pub use health::NodeHealth; | ||
pub use types::{Health, HealthInfo, HealthStatus}; | ||
pub use time::{TimeChecker, Error}; | ||
|
||
/// Indicates sync status | ||
pub trait SyncStatus: ::std::fmt::Debug + Send + Sync { | ||
/// Returns true if there is a major sync happening. | ||
fn is_major_importing(&self) -> bool; | ||
|
||
/// Returns number of connected and ideal peers. | ||
fn peers(&self) -> (usize, usize); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
// Copyright 2015-2017 Parity Technologies (UK) Ltd. | ||
// This file is part of Parity. | ||
|
||
// Parity is free software: you can redistribute it and/or modify | ||
// it under the terms of the GNU General Public License as published by | ||
// the Free Software Foundation, either version 3 of the License, or | ||
// (at your option) any later version. | ||
|
||
// Parity is distributed in the hope that it will be useful, | ||
// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
// GNU General Public License for more details. | ||
|
||
// You should have received a copy of the GNU General Public License | ||
// along with Parity. If not, see <http://www.gnu.org/licenses/>. | ||
|
||
//! Base health types. | ||
|
||
/// Health API endpoint status. | ||
#[derive(Debug, PartialEq, Serialize)] | ||
pub enum HealthStatus { | ||
/// Everything's OK. | ||
#[serde(rename = "ok")] | ||
Ok, | ||
/// Node health need attention | ||
/// (the issue is not critical, but may need investigation) | ||
#[serde(rename = "needsAttention")] | ||
NeedsAttention, | ||
/// There is something bad detected with the node. | ||
#[serde(rename = "bad")] | ||
Bad | ||
} | ||
|
||
/// Represents a single check in node health. | ||
/// Cointains the status of that check and apropriate message and details. | ||
#[derive(Debug, PartialEq, Serialize)] | ||
#[serde(deny_unknown_fields)] | ||
pub struct HealthInfo<T> { | ||
/// Check status. | ||
pub status: HealthStatus, | ||
/// Human-readable message. | ||
pub message: String, | ||
/// Technical details of the check. | ||
pub details: T, | ||
} | ||
|
||
/// Node Health status. | ||
#[derive(Debug, PartialEq, Serialize)] | ||
#[serde(deny_unknown_fields)] | ||
pub struct Health { | ||
/// Status of peers. | ||
pub peers: HealthInfo<(usize, usize)>, | ||
/// Sync status. | ||
pub sync: HealthInfo<bool>, | ||
/// Time diff info. | ||
pub time: HealthInfo<i64>, | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
trailing comma?