swactor/crates/std/src/name_registry.rs
zacheryasc f4f26c9f41 major feature update
Improve the runtime, increase test coverage, add new actor types for monitoring and supervision to an `std` crate.
2026-02-13 07:11:24 +00:00

59 lines
2 KiB
Rust

use std::collections::HashMap;
use std::sync::RwLock;
use swactor::actor::ActorAddress;
use swactor::{AddrBuildHasher, AddrMap};
/// Named actor registry — maps human-readable names to actor addresses.
///
/// `RwLock<HashMap>` — same pattern as `AddressMap`. Write-rare (spawn/death),
/// read-often (lookup). A reverse map enables O(1) cleanup on actor death.
pub struct NameRegistry {
names: RwLock<HashMap<String, ActorAddress>>,
reverse: RwLock<AddrMap<String>>,
}
impl NameRegistry {
pub fn new() -> Self {
Self {
names: RwLock::new(HashMap::new()),
reverse: RwLock::new(HashMap::with_hasher(AddrBuildHasher)),
}
}
/// Register a name → address mapping. Returns `Err` if the name is already taken.
pub fn register(&self, name: String, addr: ActorAddress) -> Result<(), swactor::Error> {
let mut names = self.names.write().unwrap();
if names.contains_key(&name) {
return Err(swactor::Error::from("Name already registered"));
}
names.insert(name.clone(), addr);
drop(names);
self.reverse.write().unwrap().insert(addr, name);
Ok(())
}
/// Look up an actor address by name.
pub fn lookup(&self, name: &str) -> Option<ActorAddress> {
self.names.read().unwrap().get(name).copied()
}
/// Unregister a name, returning the address it was bound to.
pub fn unregister(&self, name: &str) -> Option<ActorAddress> {
let addr = self.names.write().unwrap().remove(name)?;
self.reverse.write().unwrap().remove(&addr);
Some(addr)
}
/// Remove a name by address (called on actor death for auto-cleanup).
pub fn unregister_by_addr(&self, addr: &ActorAddress) {
if let Some(name) = self.reverse.write().unwrap().remove(addr) {
self.names.write().unwrap().remove(&name);
}
}
/// Return all registered names.
pub fn registered_names(&self) -> Vec<String> {
self.names.read().unwrap().keys().cloned().collect()
}
}