pub struct PeerBandwidthManager {
pub config: BandwidthManagerConfig,
pub peers: HashMap<String, PeerBandwidthState>,
pub usage_snapshots: HashMap<String, VecDeque<(u64, u64, u64)>>,
pub total_bytes_sent: u64,
pub total_bytes_recv: u64,
/* private fields */
}Expand description
Manages per-peer bandwidth state, rate limiting, and fairness scheduling.
All timestamps are provided by the caller as milliseconds since an
arbitrary epoch (e.g. SystemTime::UNIX_EPOCH or Instant-derived).
This makes the manager fully testable without real-time dependencies.
Fields§
§config: BandwidthManagerConfigManager configuration.
peers: HashMap<String, PeerBandwidthState>Per-peer token-bucket state keyed by peer ID.
usage_snapshots: HashMap<String, VecDeque<(u64, u64, u64)>>Sliding-window snapshots per peer: (timestamp_ms, bytes_sent, bytes_recv).
total_bytes_sent: u64Total bytes sent across all peers since manager creation.
total_bytes_recv: u64Total bytes received across all peers since manager creation.
Implementations§
Source§impl PeerBandwidthManager
impl PeerBandwidthManager
Sourcepub fn new(config: BandwidthManagerConfig) -> Self
pub fn new(config: BandwidthManagerConfig) -> Self
Create a new manager with the given configuration.
Sourcepub fn register_peer(&mut self, peer_id: String, now: u64)
pub fn register_peer(&mut self, peer_id: String, now: u64)
Register a peer with the default limits from the manager configuration.
If the peer is already registered, the call is a no-op.
If max_peers would be exceeded, the oldest registered peer is evicted.
Sourcepub fn set_peer_limits(
&mut self,
peer_id: &str,
upload: BandwidthLimit,
download: BandwidthLimit,
) -> bool
pub fn set_peer_limits( &mut self, peer_id: &str, upload: BandwidthLimit, download: BandwidthLimit, ) -> bool
Override the upload and download limits for an already-registered peer.
Returns true on success, false if the peer is not registered.
Sourcepub fn remove_peer(&mut self, peer_id: &str) -> bool
pub fn remove_peer(&mut self, peer_id: &str) -> bool
Remove a peer from the manager.
Returns true if the peer existed and was removed.
Sourcepub fn refill_tokens(state: &mut PeerBandwidthState, now: u64)
pub fn refill_tokens(state: &mut PeerBandwidthState, now: u64)
Refill the token buckets for state based on elapsed time since the
last refill.
elapsed_s = (now_ms - last_refill_ms) / 1000.0
New tokens are calculated as elapsed_s * bytes_per_second and added
to the current token count, clamped to burst_bytes.
Sourcepub fn try_consume(
&mut self,
peer_id: &str,
bytes: u64,
direction: BandwidthDirection,
now: u64,
) -> bool
pub fn try_consume( &mut self, peer_id: &str, bytes: u64, direction: BandwidthDirection, now: u64, ) -> bool
Attempt to consume bytes from the appropriate token bucket(s).
Tokens are refilled before checking.
Returns true if the transfer is permitted, false if there are
insufficient tokens.
Sourcepub fn record_transfer(
&mut self,
peer_id: &str,
bytes_sent: u64,
bytes_recv: u64,
now: u64,
)
pub fn record_transfer( &mut self, peer_id: &str, bytes_sent: u64, bytes_recv: u64, now: u64, )
Record an unconditional transfer for a peer (no token consumption).
The snapshot is pushed to the sliding window and the manager-wide
totals are updated. Snapshots older than usage_window_ms are
dropped.
Sourcepub fn peer_usage(&self, peer_id: &str, now: u64) -> Option<BandwidthUsage>
pub fn peer_usage(&self, peer_id: &str, now: u64) -> Option<BandwidthUsage>
Compute BandwidthUsage for a peer by summing all snapshots within
the configured window ending at now.
Returns None if the peer is not registered.
Sourcepub fn top_uploaders(&self, k: usize, now: u64) -> Vec<BandwidthUsage>
pub fn top_uploaders(&self, k: usize, now: u64) -> Vec<BandwidthUsage>
Return the top-k peers by upload rate, descending.
Sourcepub fn top_downloaders(&self, k: usize, now: u64) -> Vec<BandwidthUsage>
pub fn top_downloaders(&self, k: usize, now: u64) -> Vec<BandwidthUsage>
Return the top-k peers by download rate, descending.
Sourcepub fn apply_fairness(&mut self, now: u64)
pub fn apply_fairness(&mut self, now: u64)
Apply the configured fairness policy to all registered peers.
FairnessPolicy::MaxMinFairness: Compute the sum of all peers’ upload tokens and divide evenly; clamp each peer’s token count to that fair share. The same applies to download tokens.FairnessPolicy::WeightedFair: Scale each peer’s tokens by its normalised weight (peer_weight / sum_weights), then clamp to burst.FairnessPolicy::Unrestricted: No-op.
Sourcepub fn evict_idle_peers(&mut self, now: u64, idle_threshold_ms: u64) -> usize
pub fn evict_idle_peers(&mut self, now: u64, idle_threshold_ms: u64) -> usize
Remove peers that have no snapshot newer than now - idle_threshold_ms.
Returns the number of peers evicted.
Sourcepub fn manager_stats(&self) -> BandwidthManagerStats
pub fn manager_stats(&self) -> BandwidthManagerStats
Collect aggregate statistics for the manager.
Average rates are computed from the usage window of each registered
peer at the current moment (passing now = 0 gives a snapshot of
accumulated counters without rate computation).
Auto Trait Implementations§
impl Freeze for PeerBandwidthManager
impl RefUnwindSafe for PeerBandwidthManager
impl Send for PeerBandwidthManager
impl Sync for PeerBandwidthManager
impl Unpin for PeerBandwidthManager
impl UnsafeUnpin for PeerBandwidthManager
impl UnwindSafe for PeerBandwidthManager
Blanket Implementations§
impl<T> Allocation for T
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more