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` — 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>, reverse: RwLock>, } 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 { self.names.read().unwrap().get(name).copied() } /// Unregister a name, returning the address it was bound to. pub fn unregister(&self, name: &str) -> Option { 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 { self.names.read().unwrap().keys().cloned().collect() } }