feat(#704): add <children> recipient sentinel — fan-out to direct descendants
This commit is contained in:
parent
7cc2690717
commit
36c683138d
5 changed files with 128 additions and 15 deletions
|
|
@ -44,6 +44,32 @@ pub fn parent_of(name: &str) -> Option<String> {
|
|||
read().get(name).cloned().flatten()
|
||||
}
|
||||
|
||||
/// Return the direct children of `name` — agents whose `topology.json`
|
||||
/// entry has `name` as their parent. Reads the map once and scans all
|
||||
/// entries; cheap enough for the fan-out path (one disk read per send
|
||||
/// to `<children>`).
|
||||
#[must_use]
|
||||
pub fn children_of(name: &str) -> Vec<String> {
|
||||
children_of_in(&read(), name)
|
||||
}
|
||||
|
||||
/// Pure form of [`children_of`] for unit tests.
|
||||
#[must_use]
|
||||
pub fn children_of_in(
|
||||
topo: &BTreeMap<String, Option<String>>,
|
||||
name: &str,
|
||||
) -> Vec<String> {
|
||||
topo.iter()
|
||||
.filter_map(|(agent, parent)| {
|
||||
if parent.as_deref() == Some(name) {
|
||||
Some(agent.clone())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Resolve a magic recipient sentinel (currently just
|
||||
/// [`hive_sh4re::PARENT_RECIPIENT`]) to a real broker recipient at
|
||||
/// send time. Returns an owned `String` so callers can plug it
|
||||
|
|
@ -449,4 +475,35 @@ mod tests {
|
|||
hive_sh4re::OPERATOR_RECIPIENT
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn children_of_in_returns_direct_descendants() {
|
||||
let topo = topo_three_level();
|
||||
// alice's children: bob, carol.
|
||||
let mut children = children_of_in(&topo, "alice");
|
||||
children.sort();
|
||||
assert_eq!(children, vec!["bob", "carol"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn children_of_in_manager_returns_root_level_agents() {
|
||||
let topo = topo_three_level();
|
||||
// Only alice's parent is manager; bob+carol are under alice.
|
||||
let children = children_of_in(&topo, crate::lifecycle::MANAGER_NAME);
|
||||
assert_eq!(children, vec!["alice"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn children_of_in_leaf_returns_empty() {
|
||||
let topo = topo_three_level();
|
||||
// bob and carol have no children.
|
||||
assert!(children_of_in(&topo, "bob").is_empty());
|
||||
assert!(children_of_in(&topo, "carol").is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn children_of_in_unknown_sender_returns_empty() {
|
||||
let topo = topo_three_level();
|
||||
assert!(children_of_in(&topo, "nobody").is_empty());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue