pub struct FailureDetector { /* private fields */ }Expand description
Heartbeat-based failure detector.
Tracks node health via heartbeat messages and detects failures.
Implementations§
Source§impl FailureDetector
impl FailureDetector
Sourcepub fn with_config(config: FailureDetectorConfig) -> Self
pub fn with_config(config: FailureDetectorConfig) -> Self
Create with custom config
Sourcepub fn on_failure<F>(self, f: F) -> Self
pub fn on_failure<F>(self, f: F) -> Self
Set failure callback
Sourcepub fn on_recovery<F>(self, f: F) -> Self
pub fn on_recovery<F>(self, f: F) -> Self
Set recovery callback
Sourcepub fn heartbeat(&self, node_id: u64, addr: SocketAddr)
pub fn heartbeat(&self, node_id: u64, addr: SocketAddr)
Record a heartbeat from a node
Previously the recovery callback was invoked inside
entry().and_modify(...), which holds the DashMap shard’s
write lock. A user-supplied callback that re-entered the same
shard (or any structure ordered against it) deadlocked; even
without deadlock, every concurrent heartbeat hashing to the
same shard stalled while the callback ran. The fix collects a
“should I notify?” flag inside the closure and fires the
callback after the and_modify returns, releasing the
shard lock.
Sourcepub fn check_all(&self) -> Vec<u64>
pub fn check_all(&self) -> Vec<u64>
Check all nodes for failures
Callbacks are now invoked after the iter_mut loop has
dropped its shard locks. Previously cb(*entry.key()) ran
inside the iteration, with the per-shard write lock still
held — a user-supplied callback that touched another DashMap
entry on the same shard (or re-entered the failure detector
itself via heartbeat / status) would deadlock. We collect
the failed ids first, release the iteration locks, then fire
the callbacks.
Sourcepub fn status(&self, node_id: u64) -> NodeStatus
pub fn status(&self, node_id: u64) -> NodeStatus
Get node status
Sourcepub fn failed_nodes(&self) -> Vec<u64>
pub fn failed_nodes(&self) -> Vec<u64>
Get all failed nodes
Sourcepub fn suspected_nodes(&self) -> Vec<u64>
pub fn suspected_nodes(&self) -> Vec<u64>
Get all suspected nodes
Sourcepub fn healthy_nodes(&self) -> Vec<u64>
pub fn healthy_nodes(&self) -> Vec<u64>
Get all healthy nodes
Sourcepub fn cleanup(&self) -> usize
pub fn cleanup(&self) -> usize
Clean up stale entries (nodes that have been failed for too long)
Sourcepub fn stats(&self) -> FailureStats
pub fn stats(&self) -> FailureStats
Get statistics
nodes_tracked reads the O(1) counter; the per-status tally is still
a single pass over the entries. That scan is observability-only (not on
any hot path) and is deliberately NOT replaced by per-status counters:
node status is mutated in-place via get_mut().status = ... in tests
and could be elsewhere, which would silently drift maintained counters.
The scan is always exact.
Sourcepub fn node_count(&self) -> usize
pub fn node_count(&self) -> usize
Get node count