mirror of
https://github.com/threefoldtech/mycelium.git
synced 2026-10-24 06:12:38 +00:00
tx and rx graph (to fix: circular dependency bug)
This commit is contained in:
1 parent
2886054e17
commit
dfacd9645e
3 files changed
+122
-53
No files matched your search
Generated
+11
@@ -1015,6 +1015,16 @@ dependencies = [
|
||||
"dioxus-signals",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dioxus-charts"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53ed46a5bf524783e4a3496a8ab38fbe129590d8a3e436c1297c14f96c559a1a"
|
||||
dependencies = [
|
||||
"dioxus 0.5.1",
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dioxus-cli-config"
|
||||
version = "0.5.0"
|
||||
@@ -3049,6 +3059,7 @@ name = "mycelium-ui"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"dioxus 0.5.1",
|
||||
"dioxus-charts",
|
||||
"dioxus-free-icons",
|
||||
"dioxus-logger",
|
||||
"dioxus-sortable",
|
||||
|
||||
@@ -26,3 +26,4 @@ dioxus-free-icons = { version = "0.8.6", features = [
|
||||
] }
|
||||
human_bytes = { version = "0.4.3", features = ["fast"] }
|
||||
tokio = "1.39.2"
|
||||
dioxus-charts = "0.2.0"
|
||||
@@ -1,57 +1,30 @@
|
||||
use crate::get_sort_indicator;
|
||||
use crate::{api, SearchState, ServerAddress, SortDirection};
|
||||
use dioxus::prelude::*;
|
||||
use dioxus_charts::LineChart;
|
||||
use human_bytes::human_bytes;
|
||||
use mycelium::peer_manager::PeerType;
|
||||
use std::{cmp::Ordering, collections::HashSet};
|
||||
use mycelium::peer_manager::{PeerStats, PeerType};
|
||||
use std::{
|
||||
cmp::Ordering,
|
||||
collections::{HashSet, VecDeque},
|
||||
};
|
||||
|
||||
#[component]
|
||||
fn ExpandedPeerRow(peer: mycelium::peer_manager::PeerStats, on_close: EventHandler<()>) -> Element {
|
||||
rsx! {
|
||||
tr { class: "expanded-row",
|
||||
td { colspan: "7",
|
||||
div { class: "expanded-content",
|
||||
p { "Tx bytes: {human_bytes(peer.tx_bytes as f64)}" }
|
||||
p { "Rx bytes: {human_bytes(peer.rx_bytes as f64)}" }
|
||||
button { class: "close-button",
|
||||
onclick: move |_| on_close.call(()),
|
||||
"Close"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const REFRESH_RATE_MS: u64 = 500;
|
||||
|
||||
#[component]
|
||||
pub fn Peers() -> Element {
|
||||
let server_addr = use_context::<Signal<ServerAddress>>().read().0;
|
||||
let mut peers = use_signal(|| Vec::new());
|
||||
let peers = use_signal(Vec::new);
|
||||
let mut error = use_signal(|| None::<String>);
|
||||
|
||||
let _initial_fetch = use_resource(move || async move {
|
||||
match api::get_peers(server_addr).await {
|
||||
Ok(fetched_peers) => {
|
||||
peers.set(fetched_peers);
|
||||
error.set(None);
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("Error fetching peers: {}", e);
|
||||
error.set(Some(format!(
|
||||
"An error has occurred while fetching peers: {}",
|
||||
e
|
||||
)));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let _: Coroutine<()> = use_coroutine(|_rx: UnboundedReceiver<_>| {
|
||||
to_owned![peers, server_addr];
|
||||
async move {
|
||||
loop {
|
||||
tokio::time::sleep(tokio::time::Duration::from_millis(500)).await;
|
||||
tokio::time::sleep(tokio::time::Duration::from_millis(REFRESH_RATE_MS)).await;
|
||||
match api::get_peers(server_addr).await {
|
||||
Ok(fetched_peers) => {
|
||||
println!("fetching them peers bro");
|
||||
peers.set(fetched_peers);
|
||||
error.set(None);
|
||||
}
|
||||
@@ -71,21 +44,18 @@ pub fn Peers() -> Element {
|
||||
if let Some(err) = error.read().as_ref() {
|
||||
div { class: "error-message", "{err}" }
|
||||
} else {
|
||||
{PeersTable(peers)}
|
||||
PeersTable { peers: peers }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq)]
|
||||
// Rows that have been expaneded out to show additional information
|
||||
struct ExpandedRows(HashSet<String>);
|
||||
|
||||
fn PeersTable(peers: Signal<Vec<mycelium::peer_manager::PeerStats>>) -> Element {
|
||||
#[component]
|
||||
fn PeersTable(peers: Signal<Vec<PeerStats>>) -> Element {
|
||||
let mut current_page = use_signal(|| 0);
|
||||
let items_per_page = 20;
|
||||
let mut sort_column = use_signal(|| "Protocol".to_string());
|
||||
let mut sort_direction = use_signal(|| SortDirection::Ascending);
|
||||
let peers_len = peers.len();
|
||||
let peers_len = peers.read().len();
|
||||
|
||||
let mut change_page = move |delta: i32| {
|
||||
let cur_page = *current_page.read() as i32;
|
||||
@@ -98,12 +68,13 @@ fn PeersTable(peers: Signal<Vec<mycelium::peer_manager::PeerStats>>) -> Element
|
||||
|
||||
let mut expanded_rows = use_signal(|| ExpandedRows(HashSet::new()));
|
||||
let mut toggle_row_expansion = move |peer_endpoint: String| {
|
||||
let mut expanded = expanded_rows.write();
|
||||
if expanded.0.contains(&peer_endpoint) {
|
||||
expanded.0.remove(&peer_endpoint);
|
||||
} else {
|
||||
expanded.0.insert(peer_endpoint);
|
||||
}
|
||||
expanded_rows.with_mut(|rows| {
|
||||
if rows.0.contains(&peer_endpoint) {
|
||||
rows.0.remove(&peer_endpoint);
|
||||
} else {
|
||||
rows.0.insert(peer_endpoint);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Sorting
|
||||
@@ -172,7 +143,7 @@ fn PeersTable(peers: Signal<Vec<mycelium::peer_manager::PeerStats>>) -> Element
|
||||
_ => false,
|
||||
})
|
||||
.cloned()
|
||||
.collect::<Vec<mycelium::peer_manager::PeerStats>>()
|
||||
.collect::<Vec<PeerStats>>()
|
||||
});
|
||||
|
||||
let peers_len = filtered_peers.read().len();
|
||||
@@ -250,15 +221,18 @@ fn PeersTable(peers: Signal<Vec<mycelium::peer_manager::PeerStats>>) -> Element
|
||||
}
|
||||
{
|
||||
let is_expanded = expanded_rows.read().0.contains(&peer.endpoint.to_string());
|
||||
let mut peer_signal = use_signal(|| peer.clone());
|
||||
// Update the peer_signal when the peers are fetched
|
||||
peer_signal.set(peer.clone());
|
||||
if is_expanded {
|
||||
rsx! {
|
||||
ExpandedPeerRow {
|
||||
peer: peer.clone(),
|
||||
peer: peer_signal,
|
||||
on_close: move |_| toggle_row_expansion(peer.endpoint.to_string())
|
||||
}
|
||||
}
|
||||
} else {
|
||||
rsx! { }
|
||||
rsx! {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -282,6 +256,89 @@ fn PeersTable(peers: Signal<Vec<mycelium::peer_manager::PeerStats>>) -> Element
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
fn ExpandedPeerRow(
|
||||
peer: Signal<mycelium::peer_manager::PeerStats>,
|
||||
on_close: EventHandler<()>,
|
||||
) -> Element {
|
||||
let tx_data_deque: VecDeque<f32> = VecDeque::with_capacity(20);
|
||||
let rx_data_deque: VecDeque<f32> = VecDeque::with_capacity(20);
|
||||
let mut tx_chart_data = use_signal(|| tx_data_deque);
|
||||
let mut rx_chart_data = use_signal(|| rx_data_deque);
|
||||
|
||||
let mut prev_tx = use_signal(|| 0f64);
|
||||
let mut prev_rx = use_signal(|| 0f64);
|
||||
|
||||
use_effect(move || {
|
||||
println!("yeah...");
|
||||
let current_tx = peer.read().tx_bytes as f64;
|
||||
let current_rx = peer.read().rx_bytes as f64;
|
||||
|
||||
// Calculate data flow per second
|
||||
let tx_per_second = (current_tx - *prev_tx.read()) as u64 * (1000 / REFRESH_RATE_MS);
|
||||
let rx_per_second = (current_rx - *prev_rx.read()) as u64 * (1000 / REFRESH_RATE_MS);
|
||||
|
||||
tx_chart_data.with_mut(|tx_data| {
|
||||
if tx_data.len() >= 20 {
|
||||
tx_data.pop_front();
|
||||
}
|
||||
tx_data.push_back(tx_per_second as f32);
|
||||
});
|
||||
|
||||
rx_chart_data.with_mut(|rx_data| {
|
||||
if rx_data.len() >= 20 {
|
||||
rx_data.pop_front();
|
||||
}
|
||||
rx_data.push_back(rx_per_second as f32);
|
||||
});
|
||||
});
|
||||
// Causes a circular dependency which causes the program to become unresponsive
|
||||
// prev_tx.set(peer.read().tx_bytes as f64);
|
||||
// prev_rx.set(peer.read().rx_bytes as f64);
|
||||
|
||||
rsx! {
|
||||
tr { class: "expanded-row",
|
||||
td { colspan: "7",
|
||||
div { class: "expanded-content",
|
||||
// Tx chart
|
||||
LineChart {
|
||||
show_grid: false,
|
||||
padding_top: 80,
|
||||
padding_left: 100,
|
||||
padding_right: 80,
|
||||
padding_bottom: 80,
|
||||
label_interpolation: (|v| human_bytes(v as f64).to_string()) as fn(f32)-> String,
|
||||
series: vec![tx_chart_data.read().iter().cloned().collect::<Vec<f32>>()],
|
||||
labels: (0..tx_chart_data.read().len()).map(|i| i.to_string()).collect::<Vec<String>>(),
|
||||
series_labels: vec!["Tx Bytes".into()],
|
||||
}
|
||||
// Rx chart
|
||||
LineChart {
|
||||
show_grid: false,
|
||||
padding_top: 80,
|
||||
padding_left: 100,
|
||||
padding_right: 80,
|
||||
padding_bottom: 80,
|
||||
label_interpolation: (|v| human_bytes(v as f64).to_string()) as fn(f32)-> String,
|
||||
series: vec![rx_chart_data.read().iter().cloned().collect::<Vec<f32>>()],
|
||||
labels: (0..rx_chart_data.read().len()).map(|i| i.to_string()).collect::<Vec<String>>(),
|
||||
series_labels: vec!["Rx Bytes".into()],
|
||||
}
|
||||
// p { "Tx bytes: {human_bytes(peer.read().tx_bytes as f64)}" }
|
||||
// p { "Rx bytes: {human_bytes(peer.read().rx_bytes as f64)}" }
|
||||
button { class: "close-button",
|
||||
onclick: move |_| on_close.call(()),
|
||||
"Close"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Clone, PartialEq)]
|
||||
// Rows that have been expaneded out to show additional information
|
||||
struct ExpandedRows(HashSet<String>);
|
||||
|
||||
fn sort_peers(
|
||||
peers: &mut [mycelium::peer_manager::PeerStats],
|
||||
column: &str,
|
||||
|
||||
Reference in new issue
Block a user