Skip to main content

pim_core/config/
peer_cleanup.rs

1//! Centralized peer-lifetime / cleanup configuration shared by every
2//! subsystem that maintains a peer-keyed store needing TTL-based
3//! pruning.
4//!
5//! See `plans/rfcomm-reconnect/plan.md` for the original RFCOMM-focused
6//! motivation and the decision to centralize.
7//!
8//! Each owning section embeds a `PeerCleanupConfig` as a TOML
9//! subsection (`[<owner>.peer_cleanup]`). The schema is identical
10//! across owners — only the defaults differ, because the right horizon
11//! for "Bluetooth peer unreachable" (hours) is very different from
12//! "mesh identity unseen" (months).
13//!
14//! ```toml
15//! [bluetooth_rfcomm.peer_cleanup]
16//! enabled = true
17//! max_unreachable_lifetime_s = 7200
18//! cleanup_interval_s = 3600
19//! ```
20
21use serde::{Deserialize, Serialize};
22
23/// Shared shape of every peer-cleanup subsection. Parent configs
24/// embed an instance and provide their own [`Default`] so the
25/// horizon and cadence are tuned to the kind of peer being tracked.
26#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
27pub struct PeerCleanupConfig {
28    /// Enable the periodic cleanup task for this owner. When `false`
29    /// no destructive action is taken regardless of the other
30    /// fields.
31    pub enabled: bool,
32    /// Threshold past which a peer is considered unreachable and
33    /// eligible for the destructive cleanup action. Daemon clamps
34    /// values below `MIN_LIFETIME_S` (1 hour) at runtime.
35    pub max_unreachable_lifetime_s: u64,
36    /// Interval between cleanup sweeps. Daemon clamps values below
37    /// `MIN_INTERVAL_S` (60 seconds) at runtime.
38    pub cleanup_interval_s: u64,
39}
40
41impl PeerCleanupConfig {
42    /// Bluetooth-flavoured default: cleanup ON with a 2 h horizon and
43    /// 1 h sweep. Tuned for paired BT devices that come and go on
44    /// daily timescales.
45    pub fn bluetooth_default() -> Self {
46        Self {
47            enabled: true,
48            max_unreachable_lifetime_s: 7_200,
49            cleanup_interval_s: 3_600,
50        }
51    }
52
53    /// Mesh-identity default: cleanup ON with a 90 day horizon and
54    /// daily sweep. Identity rows are cheap to recreate on next
55    /// contact (one extra handshake), so ageing them out after a
56    /// season is fine and prevents `peers_seen` from growing
57    /// indefinitely on long-running nodes.
58    pub fn mesh_identity_default() -> Self {
59        Self {
60            enabled: true,
61            max_unreachable_lifetime_s: 7_776_000,
62            cleanup_interval_s: 86_400,
63        }
64    }
65
66    /// In-memory rate-limit / discovery state default: cleanup ON
67    /// with a 7 day horizon and 1 h sweep. The map keys cost
68    /// effectively nothing per entry, but a long-running broadcaster
69    /// shouldn't accumulate entries for peers seen weeks ago.
70    pub fn ephemeral_default() -> Self {
71        Self {
72            enabled: true,
73            max_unreachable_lifetime_s: 604_800,
74            cleanup_interval_s: 3_600,
75        }
76    }
77}