From 372a6318a2234a3a1c2f50ee6673d7c92aca8865 Mon Sep 17 00:00:00 2001 From: Nehliin Date: Sat, 29 Aug 2026 10:06:41 +0200 Subject: [PATCH 1/8] Use recommended naming for tests --- bittorrent/tests/common/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bittorrent/tests/common/mod.rs b/bittorrent/tests/common/mod.rs index c44e2c43..fc9be110 100644 --- a/bittorrent/tests/common/mod.rs +++ b/bittorrent/tests/common/mod.rs @@ -106,7 +106,7 @@ pub fn init_test_environment() { env_logger::builder() .filter_level(log::LevelFilter::Trace) .init(); - let builder = PrometheusBuilder::new(); + let builder = PrometheusBuilder::new().with_recommended_naming(true); if let Err(err) = builder.install() { log::error!("failed installing PrometheusBuilder: {err}"); } From e3f25a06fe41987a820423e569a80c6d6806f82d Mon Sep 17 00:00:00 2001 From: Nehliin Date: Sat, 29 Aug 2026 10:07:04 +0200 Subject: [PATCH 2/8] Send event for bad peers --- bittorrent/src/connection_manager.rs | 22 +++++++++++++++++++--- bittorrent/src/event_loop.rs | 6 +++++- bittorrent/src/torrent.rs | 5 ++++- 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/bittorrent/src/connection_manager.rs b/bittorrent/src/connection_manager.rs index 98f5d651..d9105cb8 100644 --- a/bittorrent/src/connection_manager.rs +++ b/bittorrent/src/connection_manager.rs @@ -4,6 +4,7 @@ use std::ops::{Index, IndexMut}; use std::os::fd::{AsRawFd, RawFd}; use bytes::BufMut; +use heapless::spsc::Producer; use rayon::Scope; use slotmap::SlotMap; use slotmap::new_key_type; @@ -13,7 +14,6 @@ use socket2::SockAddr; use socket2::Socket; use socket2::Type; -use crate::PeerId; use crate::buf_ring::Bid; use crate::event_loop::EventData; use crate::event_loop::EventType; @@ -22,9 +22,10 @@ use crate::event_loop::conn_parse_and_handle_msgs; use crate::io::Io; use crate::io::SubmissionQueue; use crate::peer_comm::extended_protocol::extension_handshake_msg; -use crate::peer_comm::peer_connection::PeerConnection; +use crate::peer_comm::peer_connection::{DisconnectReason, PeerConnection}; use crate::peer_comm::peer_protocol::{self, HANDSHAKE_SIZE, parse_handshake, write_handshake}; use crate::torrent::StateRef; +use crate::{PeerId, TorrentEvent}; new_key_type! { pub struct ConnectionId; @@ -435,6 +436,7 @@ impl ConnectionManager { &mut self, io: &mut Io, state_ref: &mut StateRef<'state>, + event_tx: &mut Producer, ) { for (conn_id, entry) in self.connections.iter_mut() { let ConnectionState::Established(peer) = entry else { @@ -444,9 +446,23 @@ impl ConnectionManager { continue; }; log::warn!("Disconnect: {} reason {reason}", peer.peer_id); + let (bad_peer, _metrics_str) = match reason { + DisconnectReason::Idle => (false, "idle"), + DisconnectReason::ProtocolError(_) => (true, "protocol_error"), + DisconnectReason::InvalidMessage => (true, "invalid_message"), + DisconnectReason::RedundantConnection => (false, "redundant_connection"), + DisconnectReason::BadPeer => (true, "bad_peer"), + }; + if bad_peer + && event_tx + .enqueue(TorrentEvent::BadPeer { ip: peer.peer_addr }) + .is_err() + { + log::warn!("Failed to enqueue BadPeer event") + } #[cfg(feature = "metrics")] { - let counter = metrics::counter!("disconnects"); + let counter = metrics::counter!("disconnects", "reason" => _metrics_str); counter.increment(1); } Self::disconnect_entry(entry, conn_id, io, state_ref); diff --git a/bittorrent/src/event_loop.rs b/bittorrent/src/event_loop.rs index f5cf0496..adab2df3 100644 --- a/bittorrent/src/event_loop.rs +++ b/bittorrent/src/event_loop.rs @@ -503,7 +503,11 @@ impl<'scope, 'state: 'scope> EventLoop { last_tick = Instant::now(); // Dealt with here to make tick easier to test - connection_manager.execute_pending_disconnects(&mut io, &mut state_ref); + connection_manager.execute_pending_disconnects( + &mut io, + &mut state_ref, + &mut event_tx, + ); io.sq.sync(); } diff --git a/bittorrent/src/torrent.rs b/bittorrent/src/torrent.rs index 3952b2e6..c32b4277 100644 --- a/bittorrent/src/torrent.rs +++ b/bittorrent/src/torrent.rs @@ -2,7 +2,7 @@ use std::{ cell::OnceCell, collections::VecDeque, io::{self}, - net::{SocketAddrV4, TcpListener}, + net::{SocketAddr, SocketAddrV4, TcpListener}, path::{Path, PathBuf}, sync::mpsc::{Receiver, Sender}, time::{Duration, Instant}, @@ -308,6 +308,9 @@ pub enum TorrentEvent { /// [`TorrentProgress::total_completed`]. progress: Option, }, + BadPeer { + ip: SocketAddr + } } pub struct InitializedState { From 8e58d16b7e8f107c6c5205684812d1670902706e Mon Sep 17 00:00:00 2001 From: Nehliin Date: Sat, 29 Aug 2026 10:07:20 +0200 Subject: [PATCH 3/8] Update test --- bittorrent/src/peer_comm/tests.rs | 5 +++-- bittorrent/tests/basic_download.rs | 3 +-- bittorrent/tests/basic_seeding.rs | 4 ++-- bittorrent/tests/chained_seeding.rs | 5 +++-- bittorrent/tests/pause_resume.rs | 4 ++-- 5 files changed, 11 insertions(+), 10 deletions(-) diff --git a/bittorrent/src/peer_comm/tests.rs b/bittorrent/src/peer_comm/tests.rs index 6ae7ccdf..58783f77 100644 --- a/bittorrent/src/peer_comm/tests.rs +++ b/bittorrent/src/peer_comm/tests.rs @@ -4334,9 +4334,10 @@ fn established_connection_slot_is_kept_until_close_completes() { #[test] fn only_peers_marked_for_disconnect_are_disconnected() { let mut download_state = setup_test(); - + let mut event_q = Queue::::new(); rayon::in_place_scope(|_scope| { let mut state_ref = download_state.as_ref(); + let (mut event_tx, _event_rx) = event_q.split(); let mut connections = ConnectionManager::new(PeerId::generate(), 128); let marked = connections.insert_established_with_key(|k| generate_peer(true, k)); let kept = connections.insert_established_with_key(|k| generate_peer(true, k)); @@ -4346,7 +4347,7 @@ fn only_peers_marked_for_disconnect_are_disconnected() { &torrent::Config::default(), ); - connections.execute_pending_disconnects(&mut io, &mut state_ref); + connections.execute_pending_disconnects(&mut io, &mut state_ref, &mut event_tx); assert_eq!(scheduled_closes(&io), vec![Some(marked)]); assert!(connections.established_mut(marked).is_none()); diff --git a/bittorrent/tests/basic_download.rs b/bittorrent/tests/basic_download.rs index e542fc2f..084dfc62 100644 --- a/bittorrent/tests/basic_download.rs +++ b/bittorrent/tests/basic_download.rs @@ -73,9 +73,8 @@ fn basic_seeded_download() { TorrentEvent::MetadataComplete(_torrent) => { log::info!("METADATA COMPLETE"); } - TorrentEvent::TorrentMetrics { .. } => {} - TorrentEvent::Running { port: _ } => {} TorrentEvent::Paused => panic!("Should never pause"), + _ => {} } } } diff --git a/bittorrent/tests/basic_seeding.rs b/bittorrent/tests/basic_seeding.rs index b15ee2cd..7193e407 100644 --- a/bittorrent/tests/basic_seeding.rs +++ b/bittorrent/tests/basic_seeding.rs @@ -135,7 +135,7 @@ fn basic_seeding() { .unwrap(); } TorrentEvent::Paused => panic!("Should never pause"), - TorrentEvent::TorrentComplete | TorrentEvent::MetadataComplete(_) => {} + _ => {} } } @@ -196,7 +196,7 @@ fn basic_seeding() { log::info!("Downloader: Metadata complete"); } TorrentEvent::Paused => panic!("Should never pause"), - TorrentEvent::Running { .. } => {} + _ => {} } } } diff --git a/bittorrent/tests/chained_seeding.rs b/bittorrent/tests/chained_seeding.rs index 6b8f5673..931b9471 100644 --- a/bittorrent/tests/chained_seeding.rs +++ b/bittorrent/tests/chained_seeding.rs @@ -168,7 +168,7 @@ fn chained_seeding() { .unwrap(); } TorrentEvent::Paused => panic!("Should never pause"), - TorrentEvent::TorrentComplete | TorrentEvent::MetadataComplete(_) => {} + _ => {} } } @@ -236,6 +236,7 @@ fn chained_seeding() { TorrentEvent::MetadataComplete(_) => { log::info!("Middle peer: Metadata complete"); } + _ => {} } } @@ -289,7 +290,7 @@ fn chained_seeding() { log::info!("Leecher: Metadata complete"); } TorrentEvent::Paused => panic!("Should never pause"), - TorrentEvent::Running { .. } => {} + _ => {} } } } diff --git a/bittorrent/tests/pause_resume.rs b/bittorrent/tests/pause_resume.rs index 5bc4f3ae..48817f47 100644 --- a/bittorrent/tests/pause_resume.rs +++ b/bittorrent/tests/pause_resume.rs @@ -117,9 +117,8 @@ fn pause_resume() { vec![format!("127.0.0.1:{}", port).parse().unwrap()], )); } - TorrentEvent::TorrentMetrics { .. } => {} TorrentEvent::Paused => panic!("Seeder should never pause"), - TorrentEvent::TorrentComplete | TorrentEvent::MetadataComplete(_) => {} + _ => {} } } @@ -234,6 +233,7 @@ fn pause_resume() { TorrentEvent::MetadataComplete(_) => { log::info!("Downloader: Metadata complete"); } + _ => {} } } } From 0d0ad8455a4f4b484fcce1cb169fdabd31f179e3 Mon Sep 17 00:00:00 2001 From: Nehliin Date: Sat, 29 Aug 2026 10:07:41 +0200 Subject: [PATCH 4/8] Update dashboard --- dashboards.json | 4165 ++++++++++++++++++++++++++++------------------- 1 file changed, 2525 insertions(+), 1640 deletions(-) diff --git a/dashboards.json b/dashboards.json index 05f0c6f3..d3c00e10 100644 --- a/dashboards.json +++ b/dashboards.json @@ -1,1757 +1,2642 @@ { - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": { - "type": "grafana", - "uid": "-- Grafana --" - }, - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "type": "dashboard" - } - ] + "apiVersion": "dashboard.grafana.app/v2", + "kind": "Dashboard", + "metadata": { + "name": "eebvxemmfqh34d", + "namespace": "default", + "uid": "f5d225d6-af1a-4412-a529-3323e64ee049", + "resourceVersion": "1787991154702015", + "generation": 9, + "creationTimestamp": "2026-06-25T10:37:40Z", + "labels": { + "grafana.app/deprecatedInternalID": "1" + }, + "annotations": { + "grafana.app/createdBy": "user:efq6y55sgbi0wc", + "grafana.app/folder": "", + "grafana.app/saved-from-ui": "Grafana v13.1.0 (b309c9bb3b)", + "grafana.app/updatedBy": "user:efq6y55sgbi0wc", + "grafana.app/updatedTimestamp": "2026-08-29T08:12:34Z" + } }, - "editable": true, - "fiscalYearStartMonth": 0, - "graphTooltip": 0, - "id": 1, - "links": [], - "panels": [ - { - "datasource": { - "type": "prometheus", - "uid": "der4co44rndogd" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisBorderShow": false, - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "barWidthFactor": 0.6, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "insertNulls": false, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" + "spec": { + "annotations": [ + { + "kind": "AnnotationQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "grafana", + "version": "v0", + "datasource": { + "name": "-- Grafana --" }, - "thresholdsStyle": { - "mode": "off" + "spec": {} + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "builtIn": true + } + } + ], + "cursorSync": "Off", + "editable": true, + "elements": { + "panel-1": { + "kind": "Panel", + "spec": { + "id": 1, + "title": "Throughput", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "der4co44rndogd" + }, + "spec": { + "disableTextWrap": false, + "editorMode": "builder", + "expr": "sum by(job) (peer_throughput_bytes)", + "fullMetaSearch": false, + "includeNullMetadata": false, + "instant": true, + "legendFormat": "{{peer_id}}", + "range": true, + "useBackend": false + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} } }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" + "vizConfig": { + "kind": "VizConfig", + "group": "timeseries", + "version": "13.1.0", + "spec": { + "options": { + "annotations": { + "clustering": -1, + "multiLane": false + }, + "legend": { + "calcs": [], + "displayMode": "list", + "enableFacetedFilter": false, + "overflow": "ellipsis", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } }, - { - "color": "red", - "value": 80 + "fieldConfig": { + "defaults": { + "unit": "Bps", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + }, + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + } + }, + "overrides": [] } - ] + } } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 0 - }, - "id": 14, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "hideZeros": false, - "mode": "single", - "sort": "none" } }, - "pluginVersion": "12.0.2", - "targets": [ - { - "disableTextWrap": false, - "editorMode": "builder", - "expr": "network_write_blocked", - "fullMetaSearch": false, - "includeNullMetadata": true, - "legendFormat": "__auto", - "range": true, - "refId": "A", - "useBackend": false - } - ], - "title": "Network write blocks", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "der4co44rndogd" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisBorderShow": false, - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "barWidthFactor": 0.6, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "insertNulls": false, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" + "panel-10": { + "kind": "Panel", + "spec": { + "id": 10, + "title": "CQE wait time hit", + "description": "total number of wait time hits", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "der4co44rndogd" + }, + "spec": { + "disableTextWrap": false, + "editorMode": "builder", + "expr": "cqe_wait_time_hit_total", + "fullMetaSearch": false, + "includeNullMetadata": true, + "legendFormat": "total cqe_wait_time_hit", + "range": true, + "useBackend": false + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} } }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "{__name__=\"peer_connect_attempts\", instance=\"host.containers.internal:9000\", job=\"vortex\"}" - }, - "properties": [ - { - "id": "custom.lineStyle", - "value": { - "dash": [ - 10, - 10 - ], - "fill": "dash" + "vizConfig": { + "kind": "VizConfig", + "group": "timeseries", + "version": "13.1.0", + "spec": { + "options": { + "annotations": { + "clustering": -1, + "multiLane": false + }, + "legend": { + "calcs": [], + "displayMode": "list", + "enableFacetedFilter": false, + "overflow": "ellipsis", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" } + }, + "fieldConfig": { + "defaults": { + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + }, + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + } + }, + "overrides": [] } - ] + } } - ] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 0 - }, - "id": 7, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "hideZeros": false, - "mode": "single", - "sort": "none" } }, - "pluginVersion": "12.0.2", - "targets": [ - { - "editorMode": "code", - "expr": "peer_connect_attempts_total", - "legendFormat": "connect_attempts", - "range": true, - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "eek7csbvj1l34d" - }, - "editorMode": "code", - "expr": "peer_connect_timeout_total", - "hide": false, - "instant": false, - "legendFormat": "timeouts", - "range": true, - "refId": "B" - }, - { - "datasource": { - "type": "prometheus", - "uid": "eek7csbvj1l34d" - }, - "editorMode": "code", - "expr": "peer_connect_success_total", - "hide": false, - "instant": false, - "legendFormat": "success", - "range": true, - "refId": "C" - }, - { - "datasource": { - "type": "prometheus", - "uid": "eek7csbvj1l34d" - }, - "expr": "", - "hide": false, - "instant": false, - "range": true, - "refId": "D" - } - ], - "title": "Connection success ratio", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "der4co44rndogd" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisBorderShow": false, - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "barWidthFactor": 0.6, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "insertNulls": false, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" + "panel-11": { + "kind": "Panel", + "spec": { + "id": 11, + "title": "disk operations", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "der4co44rndogd" + }, + "spec": { + "disableTextWrap": false, + "editorMode": "builder", + "expr": "disk_write_time_ms{quantile=\"0.99\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "legendFormat": "Write p 0.99", + "range": true, + "useBackend": false + } + }, + "refId": "A", + "hidden": false + } + }, + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "der4co44rndogd" + }, + "spec": { + "disableTextWrap": false, + "editorMode": "builder", + "expr": "disk_read_time_ms{quantile=\"0.99\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "Read p 0.99", + "range": true, + "useBackend": false + } + }, + "refId": "B", + "hidden": false + } + }, + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "der4co44rndogd" + }, + "spec": { + "disableTextWrap": false, + "editorMode": "code", + "expr": "rate(disk_write_time_ms_sum[1m]) / rate(disk_write_time_ms_count[1m])", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "Average disk write time", + "range": true, + "useBackend": false + } + }, + "refId": "C", + "hidden": false + } + }, + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "der4co44rndogd" + }, + "spec": { + "editorMode": "code", + "expr": "rate(disk_read_time_ms_sum[1m]) / rate(disk_read_time_ms_count[1m])", + "instant": false, + "legendFormat": "Average disk read time", + "range": true + } + }, + "refId": "D", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} } }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" + "vizConfig": { + "kind": "VizConfig", + "group": "timeseries", + "version": "13.1.0", + "spec": { + "options": { + "annotations": { + "clustering": -1, + "multiLane": false + }, + "legend": { + "calcs": [], + "displayMode": "list", + "enableFacetedFilter": false, + "overflow": "ellipsis", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } }, - { - "color": "red", - "value": 80 + "fieldConfig": { + "defaults": { + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + }, + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + } + }, + "overrides": [] } - ] + } } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 8 - }, - "id": 13, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "hideZeros": false, - "mode": "single", - "sort": "none" - } - }, - "pluginVersion": "12.0.2", - "targets": [ - { - "disableTextWrap": false, - "editorMode": "builder", - "expr": "buffer_lifetime_ms{quantile=\"0.999\"}", - "fullMetaSearch": false, - "includeNullMetadata": true, - "legendFormat": "__auto", - "range": true, - "refId": "A", - "useBackend": false } - ], - "title": "Buffer pool lifetime p 999 ms", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "der4co44rndogd" }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisBorderShow": false, - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "barWidthFactor": 0.6, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "insertNulls": false, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" + "panel-12": { + "kind": "Panel", + "spec": { + "id": 12, + "title": "Write buffer pool", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "der4co44rndogd" + }, + "spec": { + "disableTextWrap": false, + "editorMode": "builder", + "expr": "write_pool_allocated_buffers", + "fullMetaSearch": false, + "includeNullMetadata": true, + "legendFormat": "allocated", + "range": true, + "useBackend": false + } + }, + "refId": "A", + "hidden": false + } + }, + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "der4co44rndogd" + }, + "spec": { + "disableTextWrap": false, + "editorMode": "builder", + "expr": "write_pool_free_buffers", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "free", + "range": true, + "useBackend": false + } + }, + "refId": "B", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} } }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" + "vizConfig": { + "kind": "VizConfig", + "group": "timeseries", + "version": "13.1.0", + "spec": { + "options": { + "annotations": { + "clustering": -1, + "multiLane": false + }, + "legend": { + "calcs": [], + "displayMode": "list", + "enableFacetedFilter": false, + "overflow": "ellipsis", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } }, - { - "color": "red", - "value": 80 + "fieldConfig": { + "defaults": { + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + }, + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + } + }, + "overrides": [] } - ] + } } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 8 - }, - "id": 3, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "hideZeros": false, - "mode": "single", - "sort": "none" - } - }, - "pluginVersion": "12.0.2", - "targets": [ - { - "disableTextWrap": false, - "editorMode": "code", - "expr": "rtt{quantile=\"0.95\", job=\"vortex\"}", - "fullMetaSearch": false, - "includeNullMetadata": true, - "legendFormat": "{{peer_id}}", - "range": true, - "refId": "A", - "useBackend": false } - ], - "title": "RTT p95", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "der4co44rndogd" }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisBorderShow": false, - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "barWidthFactor": 0.6, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "insertNulls": false, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" + "panel-13": { + "kind": "Panel", + "spec": { + "id": 13, + "title": "Buffer pool lifetime p 999 ms", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "der4co44rndogd" + }, + "spec": { + "disableTextWrap": false, + "editorMode": "builder", + "expr": "buffer_lifetime_ms{quantile=\"0.999\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "legendFormat": "__auto", + "range": true, + "useBackend": false + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} } }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" + "vizConfig": { + "kind": "VizConfig", + "group": "timeseries", + "version": "13.1.0", + "spec": { + "options": { + "annotations": { + "clustering": -1, + "multiLane": false + }, + "legend": { + "calcs": [], + "displayMode": "list", + "enableFacetedFilter": false, + "overflow": "ellipsis", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } }, - { - "color": "red", - "value": 80 + "fieldConfig": { + "defaults": { + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + }, + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + } + }, + "overrides": [] } - ] + } } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 16 - }, - "id": 12, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "hideZeros": false, - "mode": "single", - "sort": "none" } }, - "pluginVersion": "12.0.2", - "targets": [ - { - "disableTextWrap": false, - "editorMode": "builder", - "expr": "write_pool_allocated_buffers", - "fullMetaSearch": false, - "includeNullMetadata": true, - "legendFormat": "allocated", - "range": true, - "refId": "A", - "useBackend": false - }, - { - "datasource": { - "type": "prometheus", - "uid": "der4co44rndogd" - }, - "disableTextWrap": false, - "editorMode": "builder", - "expr": "write_pool_free_buffers", - "fullMetaSearch": false, - "hide": false, - "includeNullMetadata": true, - "instant": false, - "legendFormat": "free", - "range": true, - "refId": "B", - "useBackend": false - } - ], - "title": "Write buffer pool", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "der4co44rndogd" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisBorderShow": false, - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "barWidthFactor": 0.6, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "insertNulls": false, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" + "panel-14": { + "kind": "Panel", + "spec": { + "id": 14, + "title": "Network write blocks", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "cfq6z5qd566m8c" + }, + "spec": { + "disableTextWrap": false, + "editorMode": "builder", + "expr": "network_write_blocked_total", + "fullMetaSearch": false, + "includeNullMetadata": true, + "legendFormat": "__auto", + "range": true, + "useBackend": false + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} } }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" + "vizConfig": { + "kind": "VizConfig", + "group": "timeseries", + "version": "13.1.0", + "spec": { + "options": { + "annotations": { + "clustering": -1, + "multiLane": false + }, + "legend": { + "calcs": [], + "displayMode": "list", + "enableFacetedFilter": false, + "overflow": "ellipsis", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } }, - { - "color": "red", - "value": 80 + "fieldConfig": { + "defaults": { + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + }, + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + } + }, + "overrides": [] } - ] + } } - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "{__name__=\"num_unchoked\", instance=\"host.containers.internal:9000\", job=\"vortex\"}" - }, - "properties": [ - { - "id": "custom.lineStyle", - "value": { - "dash": [ - 10, - 10 - ], - "fill": "dash" + } + }, + "panel-15": { + "kind": "Panel", + "spec": { + "id": 15, + "title": "Disconnects", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "cfq6z5qd566m8c" + }, + "spec": { + "editorMode": "builder", + "expr": "sum by(reason) (disconnects_total)", + "format": "time_series", + "legendFormat": "__auto", + "range": true + } + }, + "refId": "A", + "hidden": false + } } - } - ] + ], + "transformations": [], + "queryOptions": {} + } }, - { - "__systemRef": "hideSeriesFrom", - "matcher": { - "id": "byNames", + "vizConfig": { + "kind": "VizConfig", + "group": "timeseries", + "version": "13.1.0", + "spec": { "options": { - "mode": "exclude", - "names": [ - "num_connections" - ], - "prefix": "All except:", - "readOnly": true - } - }, - "properties": [ - { - "id": "custom.hideFrom", - "value": { - "legend": false, - "tooltip": false, - "viz": true + "annotations": { + "clustering": -1, + "multiLane": false + }, + "legend": { + "calcs": [], + "displayMode": "list", + "enableFacetedFilter": false, + "overflow": "ellipsis", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" } + }, + "fieldConfig": { + "defaults": { + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + }, + "color": { + "mode": "palette-classic", + "seriesBy": "last" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "bars", + "fillOpacity": 70, + "gradientMode": "hue", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineStyle": { + "fill": "solid" + }, + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": true, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + } + }, + "overrides": [] } - ] + } } - ] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 16 - }, - "id": 6, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "hideZeros": false, - "mode": "single", - "sort": "none" } }, - "pluginVersion": "12.0.2", - "targets": [ - { - "disableTextWrap": false, - "editorMode": "builder", - "expr": "num_connections", - "fullMetaSearch": false, - "includeNullMetadata": true, - "legendFormat": "num_connections", - "range": true, - "refId": "A", - "useBackend": false - }, - { - "datasource": { - "type": "prometheus", - "uid": "eek7csbvj1l34d" - }, - "disableTextWrap": false, - "editorMode": "builder", - "expr": "num_unchoked", - "fullMetaSearch": false, - "hide": false, - "includeNullMetadata": true, - "instant": false, - "legendFormat": "num_unchoked", - "range": true, - "refId": "B", - "useBackend": false - }, - { - "datasource": { - "type": "prometheus", - "uid": "eek7csbvj1l34d" - }, - "editorMode": "code", - "expr": "num_pending_connections", - "hide": false, - "instant": false, - "legendFormat": "num_pending_connections", - "range": true, - "refId": "C" - }, - { - "datasource": { - "type": "prometheus", - "uid": "eek7csbvj1l34d" - }, - "editorMode": "code", - "expr": "", - "hide": false, - "instant": false, - "legendFormat": "num_snubbed", - "range": true, - "refId": "D" - }, - { - "datasource": { - "type": "prometheus", - "uid": "eek7csbvj1l34d" - }, - "disableTextWrap": false, - "editorMode": "code", - "expr": "sum by(job) (peer_snubbed)", - "fullMetaSearch": false, - "hide": false, - "includeNullMetadata": true, - "instant": false, - "legendFormat": "num_snubbed", - "range": true, - "refId": "E", - "useBackend": false - }, - { - "datasource": { - "type": "prometheus", - "uid": "eek7csbvj1l34d" + "panel-2": { + "kind": "Panel", + "spec": { + "id": 2, + "title": "Queue size", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "der4co44rndogd" + }, + "spec": { + "disableTextWrap": false, + "editorMode": "builder", + "expr": "peer_queued", + "fullMetaSearch": false, + "includeNullMetadata": true, + "legendFormat": "{{peer_id}}", + "range": true, + "useBackend": false + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } }, - "editorMode": "code", - "expr": "sum by(job) (peer_endgame)", - "hide": false, - "instant": false, - "legendFormat": "endgame", - "range": true, - "refId": "F" + "vizConfig": { + "kind": "VizConfig", + "group": "timeseries", + "version": "13.1.0", + "spec": { + "options": { + "annotations": { + "clustering": -1, + "multiLane": false + }, + "legend": { + "calcs": [], + "displayMode": "list", + "enableFacetedFilter": false, + "overflow": "ellipsis", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "fieldConfig": { + "defaults": { + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + }, + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + } + }, + "overrides": [] + } + } + } } - ], - "title": "Connections", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "der4co44rndogd" }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisBorderShow": false, - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "barWidthFactor": 0.6, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "insertNulls": false, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" + "panel-3": { + "kind": "Panel", + "spec": { + "id": 3, + "title": "RTT p95", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "der4co44rndogd" + }, + "spec": { + "disableTextWrap": false, + "editorMode": "code", + "expr": "rtt{quantile=\"0.95\", job=\"vortex\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "legendFormat": "{{peer_id}}", + "range": true, + "useBackend": false + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} } }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" + "vizConfig": { + "kind": "VizConfig", + "group": "timeseries", + "version": "13.1.0", + "spec": { + "options": { + "annotations": { + "clustering": -1, + "multiLane": false + }, + "legend": { + "calcs": [], + "displayMode": "list", + "enableFacetedFilter": false, + "overflow": "ellipsis", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } }, - { - "color": "red", - "value": 80 + "fieldConfig": { + "defaults": { + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + }, + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + } + }, + "overrides": [] } - ] + } } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 24 - }, - "id": 11, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "hideZeros": false, - "mode": "single", - "sort": "none" } }, - "pluginVersion": "12.0.2", - "targets": [ - { - "disableTextWrap": false, - "editorMode": "builder", - "expr": "disk_write_time_ms{quantile=\"0.99\"}", - "fullMetaSearch": false, - "includeNullMetadata": true, - "legendFormat": "Write p 0.99", - "range": true, - "refId": "A", - "useBackend": false - }, - { - "datasource": { - "type": "prometheus", - "uid": "der4co44rndogd" - }, - "disableTextWrap": false, - "editorMode": "builder", - "expr": "disk_read_time_ms{quantile=\"0.99\"}", - "fullMetaSearch": false, - "hide": false, - "includeNullMetadata": true, - "instant": false, - "legendFormat": "Read p 0.99", - "range": true, - "refId": "B", - "useBackend": false - }, - { - "datasource": { - "type": "prometheus", - "uid": "der4co44rndogd" - }, - "disableTextWrap": false, - "editorMode": "code", - "expr": "rate(disk_write_time_ms_sum[1m]) / rate(disk_write_time_ms_count[1m])", - "fullMetaSearch": false, - "hide": false, - "includeNullMetadata": true, - "instant": false, - "legendFormat": "Average disk write time", - "range": true, - "refId": "C", - "useBackend": false - }, - { - "datasource": { - "type": "prometheus", - "uid": "der4co44rndogd" + "panel-4": { + "kind": "Panel", + "spec": { + "id": 4, + "title": "Peer inflight", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "der4co44rndogd" + }, + "spec": { + "disableTextWrap": false, + "editorMode": "builder", + "expr": "peer_inflight", + "fullMetaSearch": false, + "includeNullMetadata": true, + "legendFormat": "inflight {{peer_id}}", + "range": true, + "useBackend": false + } + }, + "refId": "A", + "hidden": false + } + }, + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "der4co44rndogd" + }, + "spec": { + "disableTextWrap": false, + "editorMode": "builder", + "expr": "peer_target_inflight", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "target inflight {{peer_id}}", + "range": true, + "useBackend": false + } + }, + "refId": "B", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } }, - "editorMode": "code", - "expr": "rate(disk_read_time_ms_sum[1m]) / rate(disk_read_time_ms_count[1m])", - "hide": false, - "instant": false, - "legendFormat": "Average disk read time", - "range": true, - "refId": "D" + "vizConfig": { + "kind": "VizConfig", + "group": "timeseries", + "version": "13.1.0", + "spec": { + "options": { + "annotations": { + "clustering": -1, + "multiLane": false + }, + "legend": { + "calcs": [], + "displayMode": "list", + "enableFacetedFilter": false, + "overflow": "ellipsis", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "fieldConfig": { + "defaults": { + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + }, + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineStyle": { + "fill": "solid" + }, + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + } + }, + "overrides": [ + { + "matcher": { + "id": "byFrameRefID", + "options": "B" + }, + "properties": [ + { + "id": "custom.lineStyle", + "value": { + "dash": [ + 10, + 10 + ], + "fill": "dash" + } + } + ] + } + ] + } + } + } } - ], - "title": "disk operations", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "der4co44rndogd" }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisBorderShow": false, - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "barWidthFactor": 0.6, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "insertNulls": false, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" + "panel-5": { + "kind": "Panel", + "spec": { + "id": 5, + "title": "Pieces", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "cfq6z5qd566m8c" + }, + "spec": { + "disableTextWrap": false, + "editorMode": "code", + "expr": "pieces_completed_total", + "fullMetaSearch": false, + "includeNullMetadata": true, + "legendFormat": "completed", + "range": true, + "useBackend": false + } + }, + "refId": "A", + "hidden": false + } + }, + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "cfq6z5qd566m8c" + }, + "spec": { + "disableTextWrap": false, + "editorMode": "builder", + "expr": "pieces_allocated", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "allocated", + "range": true, + "useBackend": false + } + }, + "refId": "B", + "hidden": false + } + }, + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "cfq6z5qd566m8c" + }, + "spec": { + "editorMode": "code", + "expr": "irate(pieces_completed_total[1s])", + "instant": false, + "legendFormat": "completed_rate", + "range": true + } + }, + "refId": "C", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} } }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" + "vizConfig": { + "kind": "VizConfig", + "group": "timeseries", + "version": "13.1.0", + "spec": { + "options": { + "annotations": { + "clustering": -1, + "multiLane": false + }, + "legend": { + "calcs": [], + "displayMode": "list", + "enableFacetedFilter": false, + "overflow": "ellipsis", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } }, - { - "color": "red", - "value": 80 + "fieldConfig": { + "defaults": { + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + }, + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + } + }, + "overrides": [] } - ] - }, - "unit": "Bps" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 24 - }, - "id": 1, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "hideZeros": false, - "mode": "single", - "sort": "none" + } + } } }, - "pluginVersion": "12.0.2", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "aebvmdvnsdatcb" + "panel-6": { + "kind": "Panel", + "spec": { + "id": 6, + "title": "Connections", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "der4co44rndogd" + }, + "spec": { + "disableTextWrap": false, + "editorMode": "builder", + "expr": "num_connections", + "fullMetaSearch": false, + "includeNullMetadata": true, + "legendFormat": "num_connections", + "range": true, + "useBackend": false + } + }, + "refId": "A", + "hidden": false + } + }, + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "der4co44rndogd" + }, + "spec": { + "disableTextWrap": false, + "editorMode": "builder", + "expr": "num_unchoked", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "num_unchoked", + "range": true, + "useBackend": false + } + }, + "refId": "B", + "hidden": false + } + }, + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "der4co44rndogd" + }, + "spec": { + "editorMode": "code", + "expr": "num_pending_connections", + "instant": false, + "legendFormat": "num_pending_connections", + "range": true + } + }, + "refId": "C", + "hidden": false + } + }, + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "der4co44rndogd" + }, + "spec": { + "editorMode": "code", + "expr": "", + "instant": false, + "legendFormat": "num_snubbed", + "range": true + } + }, + "refId": "D", + "hidden": false + } + }, + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "der4co44rndogd" + }, + "spec": { + "disableTextWrap": false, + "editorMode": "code", + "expr": "sum by(job) (peer_snubbed)", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "num_snubbed", + "range": true, + "useBackend": false + } + }, + "refId": "E", + "hidden": false + } + }, + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "der4co44rndogd" + }, + "spec": { + "editorMode": "code", + "expr": "sum by(job) (peer_endgame)", + "instant": false, + "legendFormat": "endgame", + "range": true + } + }, + "refId": "F", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } }, - "disableTextWrap": false, - "editorMode": "builder", - "expr": "sum by(job) (peer_throughput_bytes)", - "fullMetaSearch": false, - "includeNullMetadata": false, - "instant": true, - "legendFormat": "{{peer_id}}", - "range": true, - "refId": "A", - "useBackend": false + "vizConfig": { + "kind": "VizConfig", + "group": "timeseries", + "version": "13.1.0", + "spec": { + "options": { + "annotations": { + "clustering": -1, + "multiLane": false + }, + "legend": { + "calcs": [], + "displayMode": "list", + "enableFacetedFilter": false, + "overflow": "ellipsis", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "fieldConfig": { + "defaults": { + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + }, + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "{__name__=\"num_unchoked\", instance=\"host.containers.internal:9000\", job=\"vortex\"}" + }, + "properties": [ + { + "id": "custom.lineStyle", + "value": { + "dash": [ + 10, + 10 + ], + "fill": "dash" + } + } + ] + }, + { + "__systemRef": "hideSeriesFrom", + "matcher": { + "id": "byNames", + "options": { + "mode": "exclude", + "names": [ + "num_connections" + ], + "prefix": "All except:", + "readOnly": true + } + }, + "properties": [ + { + "id": "custom.hideFrom", + "value": { + "legend": false, + "tooltip": true, + "viz": true + } + } + ] + } + ] + } + } + } } - ], - "title": "Throughput", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "der4co44rndogd" }, - "description": "total number of wait time hits", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisBorderShow": false, - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "barWidthFactor": 0.6, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "insertNulls": false, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" + "panel-7": { + "kind": "Panel", + "spec": { + "id": 7, + "title": "Connection success ratio", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "cfq6z5qd566m8c" + }, + "spec": { + "editorMode": "code", + "expr": "peer_connect_attempts_total", + "legendFormat": "connect_attempts", + "range": true + } + }, + "refId": "A", + "hidden": false + } + }, + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "cfq6z5qd566m8c" + }, + "spec": { + "editorMode": "code", + "expr": "peer_connect_timeout_total", + "instant": false, + "legendFormat": "timeouts", + "range": true + } + }, + "refId": "B", + "hidden": false + } + }, + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "cfq6z5qd566m8c" + }, + "spec": { + "editorMode": "code", + "expr": "peer_connect_success_total", + "instant": false, + "legendFormat": "success", + "range": true + } + }, + "refId": "C", + "hidden": false + } + }, + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "cfq6z5qd566m8c" + }, + "spec": { + "expr": "", + "instant": false, + "range": true + } + }, + "refId": "D", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} } }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" + "vizConfig": { + "kind": "VizConfig", + "group": "timeseries", + "version": "13.1.0", + "spec": { + "options": { + "annotations": { + "clustering": -1, + "multiLane": false + }, + "legend": { + "calcs": [], + "displayMode": "list", + "enableFacetedFilter": false, + "overflow": "ellipsis", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } }, - { - "color": "red", - "value": 80 + "fieldConfig": { + "defaults": { + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + }, + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "{__name__=\"peer_connect_attempts\", instance=\"host.containers.internal:9000\", job=\"vortex\"}" + }, + "properties": [ + { + "id": "custom.lineStyle", + "value": { + "dash": [ + 10, + 10 + ], + "fill": "dash" + } + } + ] + } + ] } - ] + } } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 32 - }, - "id": 10, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "hideZeros": false, - "mode": "single", - "sort": "none" - } - }, - "pluginVersion": "12.0.2", - "targets": [ - { - "disableTextWrap": false, - "editorMode": "builder", - "expr": "cqe_wait_time_hit_total", - "fullMetaSearch": false, - "includeNullMetadata": true, - "legendFormat": "total cqe_wait_time_hit", - "range": true, - "refId": "A", - "useBackend": false } - ], - "title": "CQE wait time hit", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "der4co44rndogd" }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisBorderShow": false, - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "barWidthFactor": 0.6, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "insertNulls": false, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" + "panel-8": { + "kind": "Panel", + "spec": { + "id": 8, + "title": "Handshake success ratio", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "der4co44rndogd" + }, + "spec": { + "editorMode": "code", + "expr": "peer_handshake_attempt_total", + "legendFormat": "attempts", + "range": true + } + }, + "refId": "A", + "hidden": false + } + }, + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "der4co44rndogd" + }, + "spec": { + "editorMode": "code", + "expr": "peer_handshake_timeout_total", + "instant": false, + "legendFormat": "__auto", + "range": true + } + }, + "refId": "B", + "hidden": false + } + }, + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "der4co44rndogd" + }, + "spec": { + "editorMode": "code", + "expr": "peer_handshake_success_total", + "instant": false, + "legendFormat": "success", + "range": true + } + }, + "refId": "C", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} } }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" + "vizConfig": { + "kind": "VizConfig", + "group": "timeseries", + "version": "13.1.0", + "spec": { + "options": { + "annotations": { + "clustering": -1, + "multiLane": false + }, + "legend": { + "calcs": [], + "displayMode": "list", + "enableFacetedFilter": false, + "overflow": "ellipsis", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } }, - { - "color": "red", - "value": 80 + "fieldConfig": { + "defaults": { + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + }, + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + } + }, + "overrides": [] } - ] + } } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 32 - }, - "id": 5, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "hideZeros": false, - "mode": "single", - "sort": "none" } }, - "pluginVersion": "12.0.2", - "targets": [ - { - "disableTextWrap": false, - "editorMode": "code", - "expr": "pieces_completed", - "fullMetaSearch": false, - "includeNullMetadata": true, - "legendFormat": "completed", - "range": true, - "refId": "A", - "useBackend": false - }, - { - "datasource": { - "type": "prometheus", - "uid": "eek7csbvj1l34d" - }, - "disableTextWrap": false, - "editorMode": "builder", - "expr": "pieces_allocated", - "fullMetaSearch": false, - "hide": false, - "includeNullMetadata": true, - "instant": false, - "legendFormat": "allocated", - "range": true, - "refId": "B", - "useBackend": false - }, - { - "datasource": { - "type": "prometheus", - "uid": "eek7csbvj1l34d" + "panel-9": { + "kind": "Panel", + "spec": { + "id": 9, + "title": "Graceful disconnects", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "cfq6z5qd566m8c" + }, + "spec": { + "disableTextWrap": false, + "editorMode": "builder", + "expr": "graceful_disconnect_total", + "fullMetaSearch": false, + "includeNullMetadata": true, + "legendFormat": "__auto", + "range": true, + "useBackend": false + } + }, + "refId": "A", + "hidden": false + } + }, + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "cfq6z5qd566m8c" + }, + "spec": { + "disableTextWrap": false, + "editorMode": "builder", + "expr": "disconnects_total", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "useBackend": false + } + }, + "refId": "B", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } }, - "editorMode": "code", - "expr": "irate(pieces_completed[1s])", - "hide": false, - "instant": false, - "legendFormat": "completed_rate", - "range": true, - "refId": "C" + "vizConfig": { + "kind": "VizConfig", + "group": "timeseries", + "version": "13.1.0", + "spec": { + "options": { + "annotations": { + "clustering": -1, + "multiLane": false + }, + "legend": { + "calcs": [], + "displayMode": "list", + "enableFacetedFilter": false, + "overflow": "ellipsis", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "fieldConfig": { + "defaults": { + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + }, + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + } + }, + "overrides": [] + } + } + } } - ], - "title": "Pieces", - "type": "timeseries" + } }, - { - "datasource": { - "type": "prometheus", - "uid": "der4co44rndogd" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisBorderShow": false, - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "barWidthFactor": 0.6, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "insertNulls": false, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" + "layout": { + "kind": "GridLayout", + "spec": { + "items": [ + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 0, + "width": 12, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-14" + } } }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 + { + "kind": "GridLayoutItem", + "spec": { + "x": 12, + "y": 0, + "width": 12, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-7" } - ] - } - }, - "overrides": [ + } + }, { - "__systemRef": "hideSeriesFrom", - "matcher": { - "id": "byNames", - "options": { - "mode": "exclude", - "names": [ - "{__name__=\"graceful_disconnect\", instance=\"host.containers.internal:9000\", job=\"vortex\"}" - ], - "prefix": "All except:", - "readOnly": true + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 8, + "width": 12, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-13" } - }, - "properties": [ - { - "id": "custom.hideFrom", - "value": { - "legend": false, - "tooltip": false, - "viz": true - } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 12, + "y": 8, + "width": 12, + "height": 16, + "element": { + "kind": "ElementReference", + "name": "panel-15" } - ] - } - ] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 40 - }, - "id": 9, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "hideZeros": false, - "mode": "single", - "sort": "none" - } - }, - "pluginVersion": "12.0.2", - "targets": [ - { - "disableTextWrap": false, - "editorMode": "builder", - "expr": "graceful_disconnect_total", - "fullMetaSearch": false, - "includeNullMetadata": true, - "legendFormat": "__auto", - "range": true, - "refId": "A", - "useBackend": false - }, - { - "datasource": { - "type": "prometheus", - "uid": "der4co44rndogd" + } }, - "disableTextWrap": false, - "editorMode": "builder", - "expr": "disconnects_total", - "fullMetaSearch": false, - "hide": false, - "includeNullMetadata": true, - "instant": false, - "legendFormat": "__auto", - "range": true, - "refId": "B", - "useBackend": false - } - ], - "title": "Graceful disconnects", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "der4co44rndogd" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 16, + "width": 12, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-12" + } + } }, - "custom": { - "axisBorderShow": false, - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "barWidthFactor": 0.6, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "insertNulls": false, - "lineInterpolation": "linear", - "lineStyle": { - "fill": "solid" - }, - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 24, + "width": 12, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-11" + } } }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 + { + "kind": "GridLayoutItem", + "spec": { + "x": 12, + "y": 24, + "width": 12, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-3" } - ] - } - }, - "overrides": [ + } + }, { - "matcher": { - "id": "byFrameRefID", - "options": "B" - }, - "properties": [ - { - "id": "custom.lineStyle", - "value": { - "dash": [ - 10, - 10 - ], - "fill": "dash" - } + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 32, + "width": 12, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-10" } - ] - } - ] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 40 - }, - "id": 4, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "hideZeros": false, - "mode": "single", - "sort": "none" - } - }, - "pluginVersion": "12.0.2", - "targets": [ - { - "disableTextWrap": false, - "editorMode": "builder", - "expr": "peer_inflight", - "fullMetaSearch": false, - "includeNullMetadata": true, - "legendFormat": "inflight {{peer_id}}", - "range": true, - "refId": "A", - "useBackend": false - }, - { - "datasource": { - "type": "prometheus", - "uid": "eek7csbvj1l34d" + } }, - "disableTextWrap": false, - "editorMode": "builder", - "expr": "peer_target_inflight", - "fullMetaSearch": false, - "hide": false, - "includeNullMetadata": true, - "instant": false, - "legendFormat": "target inflight {{peer_id}}", - "range": true, - "refId": "B", - "useBackend": false - } - ], - "title": "Peer inflight", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "der4co44rndogd" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" + { + "kind": "GridLayoutItem", + "spec": { + "x": 12, + "y": 32, + "width": 12, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-6" + } + } }, - "custom": { - "axisBorderShow": false, - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "barWidthFactor": 0.6, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "insertNulls": false, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 40, + "width": 12, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-9" + } } }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 + { + "kind": "GridLayoutItem", + "spec": { + "x": 12, + "y": 40, + "width": 12, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-1" } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 48 - }, - "id": 8, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "hideZeros": false, - "mode": "single", - "sort": "none" - } - }, - "pluginVersion": "12.0.2", - "targets": [ - { - "editorMode": "code", - "expr": "peer_handshake_attempt_total", - "legendFormat": "attempts", - "range": true, - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "eek7csbvj1l34d" + } }, - "editorMode": "code", - "expr": "peer_handshake_timeout_total", - "hide": false, - "instant": false, - "legendFormat": "__auto", - "range": true, - "refId": "B" - }, - { - "datasource": { - "type": "prometheus", - "uid": "eek7csbvj1l34d" + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 48, + "width": 12, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-8" + } + } }, - "editorMode": "code", - "expr": "peer_handshake_success_total", - "hide": false, - "instant": false, - "legendFormat": "success", - "range": true, - "refId": "C" - } - ], - "title": "Handshake success ratio", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "der4co44rndogd" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" + { + "kind": "GridLayoutItem", + "spec": { + "x": 12, + "y": 48, + "width": 12, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-5" + } + } }, - "custom": { - "axisBorderShow": false, - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "barWidthFactor": 0.6, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "insertNulls": false, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 56, + "width": 12, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-2" + } } }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 + { + "kind": "GridLayoutItem", + "spec": { + "x": 12, + "y": 56, + "width": 12, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-4" } - ] + } } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 56 - }, - "id": 2, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "hideZeros": false, - "mode": "single", - "sort": "none" - } - }, - "pluginVersion": "12.0.2", - "targets": [ - { - "disableTextWrap": false, - "editorMode": "builder", - "expr": "peer_queued", - "fullMetaSearch": false, - "includeNullMetadata": true, - "legendFormat": "{{peer_id}}", - "range": true, - "refId": "A", - "useBackend": false - } + ] + } + }, + "links": [], + "liveNow": false, + "preload": false, + "tags": [], + "timeSettings": { + "timezone": "browser", + "from": "now-5m", + "to": "now", + "autoRefresh": "5s", + "autoRefreshIntervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" ], - "title": "Queue size", - "type": "timeseries" - } - ], - "preload": false, - "refresh": "5s", - "schemaVersion": 41, - "tags": [], - "templating": { - "list": [] - }, - "time": { - "from": "now-5m", - "to": "now" - }, - "timepicker": {}, - "timezone": "browser", - "title": "Throughput", - "uid": "eebvxemmfqh34d", - "version": 23 + "hideTimepicker": false, + "fiscalYearStartMonth": 0 + }, + "title": "Throughput", + "variables": [] + } } From af3fe2171e075416b12f8c6cfdddad558bd9f536 Mon Sep 17 00:00:00 2001 From: Nehliin Date: Sat, 29 Aug 2026 12:13:50 +0200 Subject: [PATCH 5/8] Add new tests --- bittorrent/src/peer_comm/tests.rs | 243 +++++++++++++++++++++++++++++- 1 file changed, 242 insertions(+), 1 deletion(-) diff --git a/bittorrent/src/peer_comm/tests.rs b/bittorrent/src/peer_comm/tests.rs index 58783f77..d9c0f112 100644 --- a/bittorrent/src/peer_comm/tests.rs +++ b/bittorrent/src/peer_comm/tests.rs @@ -6,7 +6,7 @@ use std::{ use bt_bencode::Deserializer; use bytes::Buf; -use heapless::spsc::{Producer, Queue}; +use heapless::spsc::{Consumer, Producer, Queue}; use serde::Deserialize; use crate::{ @@ -4356,6 +4356,247 @@ fn only_peers_marked_for_disconnect_are_disconnected() { }); } +// The addresses reported by every `BadPeer` event sitting in the queue. Any +// other event is unexpected in these tests and fails loudly rather than being +// silently skipped over +#[track_caller] +fn bad_peer_addrs(event_rx: &mut Consumer<'_, TorrentEvent>) -> Vec { + let mut addrs = Vec::new(); + while let Some(event) = event_rx.dequeue() { + match event { + TorrentEvent::BadPeer { ip } => addrs.push(ip), + other => panic!("unexpected event emitted: {other:?}"), + } + } + addrs +} + +#[track_caller] +fn mark_for_disconnect( + connections: &mut ConnectionManager, + addr: &str, + reason: DisconnectReason, +) -> ConnectionId { + let conn_id = connections.insert_established_with_key(|k| generate_peer(true, k)); + connections[conn_id].peer_addr = addr.parse().unwrap(); + connections[conn_id].pending_disconnect = Some(reason); + conn_id +} + +// Peers disconnected for something that is their own fault are reported to the +// client so that it can stop trusting them +#[test] +fn disconnects_that_blame_the_peer_emit_bad_peer_event() { + for (reason, addr) in [ + ( + DisconnectReason::ProtocolError("invalid piece message"), + "127.0.0.1:6881", + ), + (DisconnectReason::InvalidMessage, "127.0.0.1:6882"), + (DisconnectReason::BadPeer, "127.0.0.1:6883"), + ] { + let mut download_state = setup_test(); + let mut event_q = Queue::::new(); + rayon::in_place_scope(|_scope| { + let mut state_ref = download_state.as_ref(); + let (mut event_tx, mut event_rx) = event_q.split(); + let mut connections = ConnectionManager::new(PeerId::generate(), 128); + let described = reason.to_string(); + let conn_id = mark_for_disconnect(&mut connections, addr, reason); + let mut io = Io::new( + BackloggedSubmissionQueue::new(MockSubmissionQueue), + &torrent::Config::default(), + ); + + connections.execute_pending_disconnects(&mut io, &mut state_ref, &mut event_tx); + + assert_eq!( + bad_peer_addrs(&mut event_rx), + vec![addr.parse().unwrap()], + "\"{described}\" should be reported as a bad peer" + ); + assert!(connections.established_mut(conn_id).is_none()); + }); + } +} + +// Disconnecting for a reason that isn't the peer's fault must not get it +// blamed, it may well be a perfectly good peer to reconnect to later on +#[test] +fn disconnects_that_dont_blame_the_peer_emit_no_event() { + for reason in [ + DisconnectReason::Idle, + DisconnectReason::RedundantConnection, + ] { + let mut download_state = setup_test(); + let mut event_q = Queue::::new(); + rayon::in_place_scope(|_scope| { + let mut state_ref = download_state.as_ref(); + let (mut event_tx, mut event_rx) = event_q.split(); + let mut connections = ConnectionManager::new(PeerId::generate(), 128); + let described = reason.to_string(); + let conn_id = mark_for_disconnect(&mut connections, "127.0.0.1:6881", reason); + let mut io = Io::new( + BackloggedSubmissionQueue::new(MockSubmissionQueue), + &torrent::Config::default(), + ); + + connections.execute_pending_disconnects(&mut io, &mut state_ref, &mut event_tx); + + assert!( + bad_peer_addrs(&mut event_rx).is_empty(), + "\"{described}\" should not be reported as a bad peer" + ); + // The peer is still disconnected, it just isn't blamed for it + assert!(connections.established_mut(conn_id).is_none()); + assert_eq!(scheduled_closes(&io), vec![Some(conn_id)]); + }); + } +} + +// A single pass may tear down several peers for different reasons. Only the +// blameworthy ones are reported and each event has to carry the address of the +// peer it actually refers to +#[test] +fn only_blameworthy_peers_of_a_mixed_batch_are_reported() { + let mut download_state = setup_test(); + let mut event_q = Queue::::new(); + rayon::in_place_scope(|_scope| { + let mut state_ref = download_state.as_ref(); + let (mut event_tx, mut event_rx) = event_q.split(); + let mut connections = ConnectionManager::new(PeerId::generate(), 128); + let lied = mark_for_disconnect( + &mut connections, + "127.0.0.1:1111", + DisconnectReason::ProtocolError("invalid bitfield"), + ); + let idle = mark_for_disconnect(&mut connections, "127.0.0.1:2222", DisconnectReason::Idle); + let untrusted = mark_for_disconnect( + &mut connections, + "127.0.0.1:3333", + DisconnectReason::BadPeer, + ); + let kept = connections.insert_established_with_key(|k| generate_peer(true, k)); + let mut io = Io::new( + BackloggedSubmissionQueue::new(MockSubmissionQueue), + &torrent::Config::default(), + ); + + connections.execute_pending_disconnects(&mut io, &mut state_ref, &mut event_tx); + + // Connections are not iterated in insertion order + let mut reported = bad_peer_addrs(&mut event_rx); + reported.sort(); + assert_eq!( + reported, + vec![ + "127.0.0.1:1111".parse().unwrap(), + "127.0.0.1:3333".parse().unwrap() + ], + "the idle peer should not be blamed, and each event carries its own peer address" + ); + + for disconnected in [lied, idle, untrusted] { + assert!(connections.established_mut(disconnected).is_none()); + } + assert!(connections.established_mut(kept).is_some()); + assert_eq!(connections.num_established(), 1); + }); +} + +// A client that isn't draining its events fast enough must never keep a peer +// connected, the event is dropped instead +#[test] +fn bad_peer_is_disconnected_even_when_the_event_queue_is_full() { + let mut download_state = setup_test(); + // The usable capacity of a heapless queue is N - 1, so this holds one event + let mut event_q = Queue::::new(); + rayon::in_place_scope(|_scope| { + let mut state_ref = download_state.as_ref(); + let (mut event_tx, mut event_rx) = event_q.split(); + event_tx.enqueue(TorrentEvent::Paused).unwrap(); + assert!(!event_tx.ready(), "the queue should be full"); + + let mut connections = ConnectionManager::new(PeerId::generate(), 128); + let conn_id = mark_for_disconnect( + &mut connections, + "127.0.0.1:6881", + DisconnectReason::BadPeer, + ); + let mut io = Io::new( + BackloggedSubmissionQueue::new(MockSubmissionQueue), + &torrent::Config::default(), + ); + + connections.execute_pending_disconnects(&mut io, &mut state_ref, &mut event_tx); + + assert!(connections.established_mut(conn_id).is_none()); + assert_eq!(scheduled_closes(&io), vec![Some(conn_id)]); + // The dropped event didn't displace the one that was already queued + assert!(matches!(event_rx.dequeue(), Some(TorrentEvent::Paused))); + assert!(event_rx.dequeue().is_none()); + }); +} + +// Every disconnect is counted under its own reason, so that a single +// disconnect is one increment on one series rather than being spread out over +// all of them +#[cfg(feature = "metrics")] +#[test] +fn disconnects_are_counted_per_reason() { + use metrics::{Key, Label}; + use metrics_util::debugging::{DebugValue, DebuggingRecorder}; + use metrics_util::{CompositeKey, MetricKind}; + + let mut download_state = setup_test(); + let mut event_q = Queue::::new(); + let recorder = DebuggingRecorder::new(); + let snapshotter = recorder.snapshotter(); + + rayon::in_place_scope(|_scope| { + let mut state_ref = download_state.as_ref(); + let (mut event_tx, _event_rx) = event_q.split(); + let mut connections = ConnectionManager::new(PeerId::generate(), 128); + for reason in [ + DisconnectReason::InvalidMessage, + DisconnectReason::InvalidMessage, + DisconnectReason::RedundantConnection, + ] { + mark_for_disconnect(&mut connections, "127.0.0.1:6881", reason); + } + let mut io = Io::new( + BackloggedSubmissionQueue::new(MockSubmissionQueue), + &torrent::Config::default(), + ); + + metrics::with_local_recorder(&recorder, || { + connections.execute_pending_disconnects(&mut io, &mut state_ref, &mut event_tx); + }); + }); + + #[allow(clippy::mutable_key_type)] + let metrics = snapshotter.snapshot().into_hashmap(); + let count_for = |reason: &'static str| { + let key = CompositeKey::new( + MetricKind::Counter, + Key::from_parts("disconnects", vec![Label::new("reason", reason)]), + ); + let Some((_, _, DebugValue::Counter(count))) = metrics.get(&key) else { + panic!("no counter was recorded for reason {reason}"); + }; + *count + }; + + assert_eq!(count_for("invalid_message"), 2); + assert_eq!(count_for("redundant_connection"), 1); + // Reasons that never happened must not show up as series of their own + assert_eq!( + metrics.len(), + 2, + "only the reasons that actually occurred should be recorded" + ); +} + #[test] fn pending_connection_slot_is_kept_until_close_completes() { let mut download_state = setup_test(); From 955f3f0119752a01c90c9a578b6e834bef5258fb Mon Sep 17 00:00:00 2001 From: Nehliin Date: Sat, 29 Aug 2026 12:17:11 +0200 Subject: [PATCH 6/8] Add docs --- bittorrent/src/torrent.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/bittorrent/src/torrent.rs b/bittorrent/src/torrent.rs index c32b4277..07da1e1b 100644 --- a/bittorrent/src/torrent.rs +++ b/bittorrent/src/torrent.rs @@ -308,9 +308,10 @@ pub enum TorrentEvent { /// [`TorrentProgress::total_completed`]. progress: Option, }, - BadPeer { - ip: SocketAddr - } + /// A peer has been disconnect due to protocol errors, invalid messages + /// or that the peer trust has dropped too low due to being part of pieces + /// that received invalid piece data. + BadPeer { ip: SocketAddr }, } pub struct InitializedState { From 01ca03638b7034255a71f8e49f7b55a4ac1df433 Mon Sep 17 00:00:00 2001 From: Nehliin Date: Sat, 29 Aug 2026 12:18:21 +0200 Subject: [PATCH 7/8] rename field --- bittorrent/src/connection_manager.rs | 4 +++- bittorrent/src/peer_comm/tests.rs | 2 +- bittorrent/src/torrent.rs | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/bittorrent/src/connection_manager.rs b/bittorrent/src/connection_manager.rs index d9105cb8..41256777 100644 --- a/bittorrent/src/connection_manager.rs +++ b/bittorrent/src/connection_manager.rs @@ -455,7 +455,9 @@ impl ConnectionManager { }; if bad_peer && event_tx - .enqueue(TorrentEvent::BadPeer { ip: peer.peer_addr }) + .enqueue(TorrentEvent::BadPeer { + peer_addr: peer.peer_addr, + }) .is_err() { log::warn!("Failed to enqueue BadPeer event") diff --git a/bittorrent/src/peer_comm/tests.rs b/bittorrent/src/peer_comm/tests.rs index d9c0f112..b1f24ba8 100644 --- a/bittorrent/src/peer_comm/tests.rs +++ b/bittorrent/src/peer_comm/tests.rs @@ -4364,7 +4364,7 @@ fn bad_peer_addrs(event_rx: &mut Consumer<'_, TorrentEvent>) -> Vec let mut addrs = Vec::new(); while let Some(event) = event_rx.dequeue() { match event { - TorrentEvent::BadPeer { ip } => addrs.push(ip), + TorrentEvent::BadPeer { peer_addr: ip } => addrs.push(ip), other => panic!("unexpected event emitted: {other:?}"), } } diff --git a/bittorrent/src/torrent.rs b/bittorrent/src/torrent.rs index 07da1e1b..c8d568c2 100644 --- a/bittorrent/src/torrent.rs +++ b/bittorrent/src/torrent.rs @@ -311,7 +311,7 @@ pub enum TorrentEvent { /// A peer has been disconnect due to protocol errors, invalid messages /// or that the peer trust has dropped too low due to being part of pieces /// that received invalid piece data. - BadPeer { ip: SocketAddr }, + BadPeer { peer_addr: SocketAddr }, } pub struct InitializedState { From dfb830cde459931ef049bd1dffe8fa12997aa99f Mon Sep 17 00:00:00 2001 From: Nehliin Date: Sat, 29 Aug 2026 12:19:15 +0200 Subject: [PATCH 8/8] update cli --- cli/src/app.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cli/src/app.rs b/cli/src/app.rs index 4c0d24aa..7492ae94 100644 --- a/cli/src/app.rs +++ b/cli/src/app.rs @@ -279,6 +279,9 @@ impl<'queue, F: FnOnce(State) -> color_eyre::Result<()>> VortexApp<'queue, F> { self.total_upload_throughput .write((curr_time, tick_upload_throughput as f64)); } + TorrentEvent::BadPeer { peer_addr } => { + log::warn!("Peer forcibly disconnected due to bad behavior: {peer_addr} ") + } } }