2026-02-13 07:11:24 +00:00
|
|
|
use std::collections::HashMap;
|
2026-06-24 11:04:39 +00:00
|
|
|
|
|
|
|
|
use parking_lot::RwLock;
|
2026-02-13 07:11:24 +00:00
|
|
|
|
2026-02-24 09:12:28 +00:00
|
|
|
use crate::actor::ActorAddress;
|
|
|
|
|
use crate::{AddrBuildHasher, AddrMap};
|
2026-02-13 07:11:24 +00:00
|
|
|
|
|
|
|
|
/// Named actor registry — maps human-readable names to actor addresses.
|
|
|
|
|
pub struct NameRegistry {
|
|
|
|
|
names: RwLock<HashMap<String, ActorAddress>>,
|
|
|
|
|
reverse: RwLock<AddrMap<String>>,
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-24 09:12:28 +00:00
|
|
|
impl Default for NameRegistry {
|
|
|
|
|
fn default() -> Self {
|
|
|
|
|
Self::new()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-13 07:11:24 +00:00
|
|
|
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.
|
2026-02-24 09:12:28 +00:00
|
|
|
pub fn register(&self, name: String, addr: ActorAddress) -> Result<(), crate::Error> {
|
2026-06-24 11:04:39 +00:00
|
|
|
let mut names = self.names.write();
|
2026-02-13 07:11:24 +00:00
|
|
|
if names.contains_key(&name) {
|
2026-02-24 09:12:28 +00:00
|
|
|
return Err(crate::Error::from("Name already registered"));
|
2026-02-13 07:11:24 +00:00
|
|
|
}
|
|
|
|
|
names.insert(name.clone(), addr);
|
|
|
|
|
drop(names);
|
2026-06-24 11:04:39 +00:00
|
|
|
self.reverse.write().insert(addr, name);
|
2026-02-13 07:11:24 +00:00
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Look up an actor address by name.
|
|
|
|
|
pub fn lookup(&self, name: &str) -> Option<ActorAddress> {
|
2026-06-24 11:04:39 +00:00
|
|
|
self.names.read().get(name).copied()
|
2026-02-13 07:11:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Unregister a name, returning the address it was bound to.
|
|
|
|
|
pub fn unregister(&self, name: &str) -> Option<ActorAddress> {
|
2026-06-24 11:04:39 +00:00
|
|
|
let addr = self.names.write().remove(name)?;
|
|
|
|
|
self.reverse.write().remove(&addr);
|
2026-02-13 07:11:24 +00:00
|
|
|
Some(addr)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Remove a name by address (called on actor death for auto-cleanup).
|
|
|
|
|
pub fn unregister_by_addr(&self, addr: &ActorAddress) {
|
2026-06-24 11:04:39 +00:00
|
|
|
if let Some(name) = self.reverse.write().remove(addr) {
|
|
|
|
|
self.names.write().remove(&name);
|
2026-02-13 07:11:24 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Return all registered names.
|
|
|
|
|
pub fn registered_names(&self) -> Vec<String> {
|
2026-06-24 11:04:39 +00:00
|
|
|
self.names.read().keys().cloned().collect()
|
2026-02-13 07:11:24 +00:00
|
|
|
}
|
|
|
|
|
}
|