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}