Skip to content

Commit

Permalink
add: RSS feed for lagging nodes
Browse files Browse the repository at this point in the history
  • Loading branch information
0xB10C committed Feb 16, 2024
1 parent 56bd724 commit 081931d
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 8 deletions.
8 changes: 8 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,13 @@ async fn main() -> Result<(), MainError> {
.and(rss::with_rss_base_url(config.rss_base_url.clone()))
.and_then(rss::invalid_blocks_response);

let lagging_nodes_rss = warp::get()
.and(warp::path!("rss" / u32 / "lagging.xml"))
.and(api::with_caches(caches.clone()))
.and(api::with_networks(network_infos.clone()))
.and(rss::with_rss_base_url(config.rss_base_url.clone()))
.and_then(rss::lagging_nodes_response);

let networks_json = warp::get()
.and(warp::path!("api" / "networks.json"))
.and(api::with_networks(network_infos))
Expand Down Expand Up @@ -560,6 +567,7 @@ async fn main() -> Result<(), MainError> {
.or(networks_json)
.or(change_sse)
.or(forks_rss)
.or(lagging_nodes_rss)
.or(invalid_blocks_rss);

warp::serve(routes).run(config.address).await;
Expand Down
90 changes: 90 additions & 0 deletions src/rss.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ use std::convert::Infallible;

use crate::types::{Caches, ChainTipStatus, Fork, NetworkJson, NodeDataJson, TipInfoJson};

const THREASHOLD_NODE_LAGGING: u64 = 3; // blocks

pub fn with_rss_base_url(
base_url: String,
) -> impl Filter<Extract = (String,), Error = Infallible> + Clone {
Expand Down Expand Up @@ -169,6 +171,94 @@ pub async fn forks_response(
}
}

impl Item {
pub fn lagging_node_item(node: &NodeDataJson, height: u64) -> Item {
Item {
title: format!("Node '{}' is lagging behind", node.name),
description: format!(
"The node's active tip is on height {}, while other nodes consider a block with a height at least {} blocks higher their active tip. The node might still be synchronizing with the network or stuck.",
height,
THREASHOLD_NODE_LAGGING,
),
guid: format!("lagging-node-{}-on-{}", node.name, height),
}
}
}

pub async fn lagging_nodes_response(
network_id: u32,
caches: Caches,
network_infos: Vec<NetworkJson>,
base_url: String,
) -> Result<impl warp::Reply, Infallible> {
let caches_locked = caches.lock().await;
match caches_locked.get(&network_id) {
Some(cache) => {
let mut network_name = "";
if let Some(network) = network_infos
.iter()
.filter(|net| net.id == network_id)
.collect::<Vec<&NetworkJson>>()
.first()
{
network_name = &network.name;
}

let mut lagging_nodes: Vec<Item> = vec![];
if cache.node_data.len() > 1 {
let nodes_with_active_height: Vec<(&NodeDataJson, u64)> = cache
.node_data
.iter()
.map(|(_, node)| {
(
node,
node.tips
.iter()
.filter(|tip| tip.status == "active".to_string())
.last()
.unwrap_or(&TipInfoJson {
height: 0,
status: "active".to_string(),
hash: "dummy".to_string(),
})
.height,
)
})
.collect();
let max_height: u64 = *nodes_with_active_height
.iter()
.map(|(_, height)| height)
.max()
.unwrap_or(&0);
for (node, height) in nodes_with_active_height.iter() {
if height + THREASHOLD_NODE_LAGGING < max_height {
lagging_nodes.push(Item::lagging_node_item(node, *height));
}
}
}

let feed = Feed {
channel: Channel {
title: format!("Lagging nodes on {}", network_name),
description: format!(
"List of nodes that are more than 3 blocks behind the chain tip on the {} network.",
network_name
)
.to_string(),
link: format!("{}?network={}", base_url.clone(), network_id),
href: format!("{}/rss/{}/lagging.xml", base_url, network_id),
items: lagging_nodes,
},
};

Ok(Response::builder()
.header("content-type", "application/rss+xml")
.body(feed.to_string()))
}
None => Ok(Ok(response_unknown_network(network_infos))),
}
}

pub async fn invalid_blocks_response(
network_id: u32,
caches: Caches,
Expand Down
22 changes: 14 additions & 8 deletions www/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,20 @@
<h3>Network: <span id="network_info_name"></span></h3>
<span id="network_info_description"></span>
<br>
<span>
<img src="static/img/rss-feed-white.svg" height=18>
<a target="_blank" id="rss_recent_forks">Recent forks</a>
</span>
<span>
<img src="static/img/rss-feed-white.svg" height=18>
<a target="_blank" id="rss_invalid_blocks">Invalid blocks</a>
</span>
<p class="small">
<span>
<img src="static/img/rss-feed-white.svg" height=18>
<a target="_blank" id="rss_recent_forks">Recent forks</a>
</span>
<span>
<img src="static/img/rss-feed-white.svg" height=18>
<a target="_blank" id="rss_invalid_blocks">Invalid blocks</a>
</span>
<span>
<img src="static/img/rss-feed-white.svg" height=18>
<a target="_blank" id="rss_lagging_nodes">Lagging nodes</a>
</span>
</p>
<br>
<details style="color: var(--text-color);" open>
<summary>
Expand Down
2 changes: 2 additions & 0 deletions www/js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const networkInfoName = d3.select("#network_info_name")
const footerCustom = d3.select("#footer-custom")
const rssRecentForks = d3.select("#rss_recent_forks")
const rssInvalidBlocks = d3.select("#rss_invalid_blocks")
const rssLaggingNodes = d3.select("#rss_lagging_nodes")

const SEARCH_PARAM_NETWORK = "network"

Expand Down Expand Up @@ -55,6 +56,7 @@ function update_network() {
networkInfoDescription.text(current_network.description)
rssRecentForks.node().href = `rss/${current_network.id}/forks.xml`
rssInvalidBlocks.node().href = `rss/${current_network.id}/invalid.xml`
rssLaggingNodes.node().href = `rss/${current_network.id}/lagging.xml`
}

function set_initial_network() {
Expand Down

0 comments on commit 081931d

Please sign in to comment.