pub struct HintStore { /* private fields */ }Expand description
Node-local hint store.
The store is internally synchronised so std::sync::Arc
clones share the same per-peer queues. Operations are O(1)
with respect to the number of pending hints for the queried
peer and O(N) for HintStore::expire_now.
Implementations§
Source§impl HintStore
impl HintStore
Sourcepub fn new(max_bytes: u64) -> Self
pub fn new(max_bytes: u64) -> Self
Build a new store with the supplied byte cap.
max_bytes of zero means “no cap”; this is intended for
tests that drive enqueue/take patterns and never want to
exercise the back-pressure branch.
Sourcepub fn open<P: AsRef<Path>>(
dir: P,
max_bytes: u64,
) -> Result<Self, HintStoreOpenError>
pub fn open<P: AsRef<Path>>( dir: P, max_bytes: u64, ) -> Result<Self, HintStoreOpenError>
Build a durable store backed by per-peer segment files
under dir, replaying any segments already present.
On success the in-memory queues are pre-populated with
every intact hint found on disk whose wall-clock deadline
has not yet passed (re-anchored to the monotonic clock).
A torn trailing record in any segment is discarded
silently; see the module-level torn-tail documentation.
The replayed bytes are counted toward max_bytes, so a
store recovered from disk enforces the same combined cap
the RAM-only store does.
§Errors
HintStoreOpenError::Dirwhendircannot be created or its entries cannot be listed.HintStoreOpenError::Segmentwhen a segment file exists but cannot be opened or read (a torn tail is not an error; an unreadable file is).
§Examples
use std::time::Duration;
use dynomite::cluster::hints::HintStore;
let dir = tempfile::tempdir().unwrap();
let store = HintStore::open(dir.path(), 1024).unwrap();
store.enqueue(1, b"hi".to_vec(), Duration::from_secs(60)).unwrap();
drop(store);
let reopened = HintStore::open(dir.path(), 1024).unwrap();
assert_eq!(reopened.len_for(1), 1);Sourcepub fn enqueue(
&self,
peer_idx: u32,
payload: Vec<u8>,
ttl: Duration,
) -> Result<(), HintStoreError>
pub fn enqueue( &self, peer_idx: u32, payload: Vec<u8>, ttl: Duration, ) -> Result<(), HintStoreError>
Append a hint for peer_idx. The hint expires at
Instant::now() + ttl.
§Errors
HintStoreError::ZeroTtlwhenttlis zero.HintStoreError::EmptyPayloadwhenpayloadis empty.HintStoreError::OverCapacitywhen accepting the hint would push the cumulative payload bytes overmax_bytes.
Sourcepub fn take_for(&self, peer_idx: u32) -> Vec<Hint>
pub fn take_for(&self, peer_idx: u32) -> Vec<Hint>
Drain every pending hint for peer_idx. Hints that have
expired are dropped on the floor (and counted toward
HintStoreStats::expired_total).
Returned hints are ordered by enqueue time, oldest first.
Sourcepub fn expire_now(&self, now: Instant) -> usize
pub fn expire_now(&self, now: Instant) -> usize
Drop every hint whose deadline has passed at now.
Returns the number of hints dropped. Walks the entire
store; intended for the periodic drainer task.
Sourcepub fn len_for(&self, peer_idx: u32) -> usize
pub fn len_for(&self, peer_idx: u32) -> usize
Pending hint count for peer_idx. Useful for tests.
Sourcepub fn stats(&self) -> HintStoreStats
pub fn stats(&self) -> HintStoreStats
Snapshot the store’s accounting fields.
Sourcepub fn peers_with_hints(&self) -> Vec<u32>
pub fn peers_with_hints(&self) -> Vec<u32>
Iterate the peer indices that currently have pending hints. Used by the drainer to decide which peers to ship to without holding the inner lock across the network send.