use std::io;
use crate::IoBackend;
use crate::rt::counters::{KINDS, kind_index};
#[derive(Clone, Debug)]
#[non_exhaustive]
pub struct Stats {
pub shards: Vec<ShardStats>,
pub blocking_threads: usize,
pub off_shard_errors: ErrorCounts,
}
#[derive(Clone, Debug)]
#[non_exhaustive]
pub struct ShardStats {
pub worker: Option<usize>,
pub backend: IoBackend,
pub tasks: usize,
pub polls: u64,
pub parks: u64,
pub parked: std::time::Duration,
pub busy: std::time::Duration,
pub queue_depth: usize,
pub remote_wakes: u64,
pub ops_in_flight: usize,
pub cq_overflows: u64,
pub buffer_bytes: usize,
pub buffer_cap: usize,
pub buffer_exhausted: u64,
pub timers: usize,
pub handoffs: u64,
pub longest_poll: std::time::Duration,
pub errors: ErrorCounts,
}
#[derive(Clone, PartialEq, Eq)]
#[non_exhaustive]
pub struct ErrorCounts {
pub(crate) by_kind: [u64; KINDS.len()],
pub refused_registrations: u64,
pub accepts_out_of_descriptors: u64,
}
impl ErrorCounts {
pub fn get(&self, kind: io::ErrorKind) -> u64 {
self.by_kind[kind_index(kind)]
}
pub fn iter(&self) -> impl Iterator<Item = (io::ErrorKind, u64)> + '_ {
KINDS
.iter()
.copied()
.zip(self.by_kind.iter().copied())
.filter(|&(_, n)| n > 0)
}
}
impl Default for ErrorCounts {
fn default() -> Self {
Self {
by_kind: [0; KINDS.len()],
refused_registrations: 0,
accepts_out_of_descriptors: 0,
}
}
}
impl core::fmt::Debug for ErrorCounts {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("ErrorCounts")
.field("by_kind", &self.iter().collect::<Vec<_>>())
.field("refused_registrations", &self.refused_registrations)
.field(
"accepts_out_of_descriptors",
&self.accepts_out_of_descriptors,
)
.finish()
}
}
pub fn stats() -> Stats {
crate::rt::counters::snapshot()
}