swarm-controller: KV-store + serve per-agent status (#3341 item 2)

This commit is contained in:
damocles 2026-09-02 04:53:22 +02:00 committed by mara
commit 162b646e5b
3 changed files with 406 additions and 1 deletions

View file

@ -49,6 +49,25 @@ pub fn key(hive: &str, agent: &str) -> String {
format!("{hive}/{agent}")
}
/// The inverse of [`key`]: split a bucket key back into `(hive, agent)`.
///
/// `None` for a key with zero or more than one `/` — a hive publishing
/// under [`key`] never produces one, so a malformed key means something
/// else wrote this bucket. Splitting on the *first* `/` would be equally
/// valid today (neither name can contain one), but this rejects rather
/// than guesses, so a future name-charset change can't silently start
/// misreading old keys.
#[must_use]
pub fn split_key(key: &str) -> Option<(&str, &str)> {
let mut parts = key.splitn(3, '/');
let hive = parts.next()?;
let agent = parts.next()?;
if parts.next().is_some() {
return None;
}
Some((hive, agent))
}
/// One agent's status snapshot, as published under [`key`].
///
/// Mirrors the tuple `container_view::read_agent_status_live` returns on
@ -106,13 +125,28 @@ pub async fn open_or_create(
#[cfg(test)]
mod tests {
use super::{AgentStatus, key};
use super::{AgentStatus, key, split_key};
#[test]
fn key_joins_hive_and_agent_with_a_slash() {
assert_eq!(key("prod", "iris"), "prod/iris");
}
#[test]
fn split_key_is_the_inverse_of_key() {
assert_eq!(split_key(&key("prod", "iris")), Some(("prod", "iris")));
}
#[test]
fn split_key_rejects_a_key_with_no_slash() {
assert_eq!(split_key("iris"), None);
}
#[test]
fn split_key_rejects_a_key_with_two_slashes() {
assert_eq!(split_key("prod/iris/extra"), None);
}
#[test]
fn agent_status_round_trips() {
let status = AgentStatus {