Skip to main content

hopr_transport_session/
counters.rs

1//! Process-global packet-flow diagnostic counters for the throughput stress harness.
2//!
3//! These counters were originally defined in `hopr-utils::parallelize`, but they encode
4//! HOPR session/routing domain concepts (session inbox, routing resolution, SPHINX encode
5//! stage) rather than generic parallelisation primitives. They therefore live here in the
6//! transport-session crate instead of the generic `hopr-utilities` crate.
7//!
8//! Each counter is a plain process-global atomic, incremented on hot paths across the
9//! transport/session pipeline and read (as deltas) by the load generator. They are not
10//! gated on any feature so they are available in every build, including test builds.
11
12use std::sync::atomic::{AtomicUsize, Ordering};
13
14/// Cumulative count of application data packets dropped because the session inbox
15/// channel was full (`try_send` returned `TrySendError::Full`).
16pub static SESSION_INBOX_DROPS: AtomicUsize = AtomicUsize::new(0);
17
18/// Returns the cumulative session inbox drop count.
19#[inline]
20pub fn session_inbox_drop_count() -> usize {
21    SESSION_INBOX_DROPS.load(Ordering::Relaxed)
22}
23
24/// Cumulative count of application data packets dropped because the session inbox
25/// channel was closed (`try_send` returned `TrySendError::Disconnected`): the session
26/// data sink was dropped while the slot was still registered — a benign teardown race,
27/// not the backpressure that [`SESSION_INBOX_DROPS`] counts.
28pub static SESSION_INBOX_CLOSED_DROPS: AtomicUsize = AtomicUsize::new(0);
29
30/// Returns the cumulative count of packets dropped because the session inbox was closed.
31#[inline]
32pub fn session_inbox_closed_drop_count() -> usize {
33    SESSION_INBOX_CLOSED_DROPS.load(Ordering::Relaxed)
34}
35
36/// Cumulative count of data packets dropped because no matching session slot was
37/// found in the session manager (`UnknownData` / unestablished-session path).
38pub static SESSION_UNKNOWN_DATA_DROPS: AtomicUsize = AtomicUsize::new(0);
39
40/// Returns the cumulative UnknownData drop count.
41#[inline]
42pub fn session_unknown_data_drop_count() -> usize {
43    SESSION_UNKNOWN_DATA_DROPS.load(Ordering::Relaxed)
44}
45
46/// Cumulative count of data packets dispatched as "unrelated" — reached dispatch_message
47/// but matched neither the session protocol tag nor any session application tag.
48pub static SESSION_UNRELATED_DATA_DISPATCHES: AtomicUsize = AtomicUsize::new(0);
49
50/// Returns the cumulative unrelated dispatch count.
51#[inline]
52pub fn session_unrelated_dispatch_count() -> usize {
53    SESSION_UNRELATED_DATA_DISPATCHES.load(Ordering::Relaxed)
54}
55
56/// Cumulative count of outgoing packets dropped because their return route still had no SURB
57/// when the resolution wait ran out.
58///
59/// Separate from [`ROUTING_RESOLUTION_FAILURES`] because it means something different and
60/// actionable: a counterparty has stopped replenishing SURBs and is not coming back, rather than a
61/// route that could not be computed. A non-zero and growing value names the condition that used to
62/// stall a node's entire egress indefinitely.
63pub static ROUTING_RESOLUTION_SURB_TIMEOUTS: AtomicUsize = AtomicUsize::new(0);
64
65/// Returns the cumulative count of packets dropped after waiting in vain for a return SURB.
66#[inline]
67pub fn routing_resolution_surb_timeout_count() -> usize {
68    ROUTING_RESOLUTION_SURB_TIMEOUTS.load(Ordering::Relaxed)
69}
70
71/// Cumulative count of packets that failed path/routing resolution before encoding.
72pub static ROUTING_RESOLUTION_FAILURES: AtomicUsize = AtomicUsize::new(0);
73
74/// Returns the cumulative routing resolution failure count.
75#[inline]
76pub fn routing_resolution_failure_count() -> usize {
77    ROUTING_RESOLUTION_FAILURES.load(Ordering::Relaxed)
78}
79
80/// Cumulative count of packets that successfully entered the routing resolution stage.
81pub static ROUTING_RESOLUTION_ATTEMPTS: AtomicUsize = AtomicUsize::new(0);
82
83/// Returns the cumulative routing resolution attempt count.
84#[inline]
85pub fn routing_resolution_attempt_count() -> usize {
86    ROUTING_RESOLUTION_ATTEMPTS.load(Ordering::Relaxed)
87}
88
89/// Cumulative count of packets that entered the SPHINX encode stage (spawn_encode_blocking called).
90pub static ENCODE_STAGE_ENTRIES: AtomicUsize = AtomicUsize::new(0);
91
92/// Returns the cumulative encode stage entry count.
93#[inline]
94pub fn encode_stage_entry_count() -> usize {
95    ENCODE_STAGE_ENTRIES.load(Ordering::Relaxed)
96}
97
98/// Cumulative count of calls to `smgr.dispatch_message` in SessionsManagement(0).
99/// Non-zero means packets are reaching the session manager dispatcher.
100pub static DISPATCH_MESSAGE_CALLS: AtomicUsize = AtomicUsize::new(0);
101
102/// Returns the cumulative dispatch_message call count.
103#[inline]
104pub fn dispatch_message_call_count() -> usize {
105    DISPATCH_MESSAGE_CALLS.load(Ordering::Relaxed)
106}
107
108/// Cumulative count of packets dropped by `forward_to_timeout(app_incoming)` at the ingress
109/// pipeline because `tx_from_protocol` was full for longer than `QUEUE_SEND_TIMEOUT` (50 ms).
110pub static APP_INCOMING_TIMEOUT_DROPS: AtomicUsize = AtomicUsize::new(0);
111
112/// Returns the cumulative app-incoming timeout drop count.
113#[inline]
114pub fn app_incoming_timeout_drop_count() -> usize {
115    APP_INCOMING_TIMEOUT_DROPS.load(Ordering::Relaxed)
116}