Skip to main content

bonds_core/manager/
health.rs

1use super::*;
2
3/// Health-scan concerns.
4impl BondManager {
5    /// Return broken bonds and emit BrokenDetected event for each.
6    pub fn scan_broken_bonds(&self) -> Result<Vec<Bond>, BondError> {
7        let bonds = self.list_bonds()?;
8        let mut broken = Vec::new();
9
10        for bond in bonds {
11            if let Some(reason) = Self::broken_reason(&bond) {
12                self.emit_event(BondEventPayload::BrokenDetected {
13                    bond: bond.clone(),
14                    reason,
15                });
16                broken.push(bond);
17            }
18        }
19
20        Ok(broken)
21    }
22
23    fn broken_reason(bond: &Bond) -> Option<BondBrokenReason> {
24        // exists() follows symlinks: broken symlinks report false.
25        let target_exists = bond.target().exists();
26
27        // symlink_metadata() inspects the link itself.
28        let is_symlink = bond
29            .target()
30            .symlink_metadata()
31            .map(|m| m.file_type().is_symlink())
32            .unwrap_or(false);
33
34        if !target_exists {
35            Some(BondBrokenReason::MissingTarget)
36        } else if !is_symlink {
37            Some(BondBrokenReason::TargetNotSymlink)
38        } else {
39            None
40        }
41    }
42}