pub struct NameRegistry<T> { /* private fields */ }Expand description
A namespace of names that can be bound, dialled and unbound, generic over what a bound name hands its acceptor.
What it is for. Every protocol with an in-process transport needs the
same object: a set of names, one owner per name, a queue from the dialler
to the owner, and a ceiling on how long a name may be. weida’s
weida+inproc://<bus>/<path> buses and ZeroMQ’s inproc:// endpoints are
that object twice, down to the 256-byte budget, which libzmq set first
(decisions/0010 §4.8,
docs/research/zeromq.md §11).
T is whatever binding a name entitles its owner to receive — one side of
a connection, a pipe pair, a socket. The registry never looks at it.
Scope is the holder’s choice. A static registry is a process-wide
namespace, which is what a library with a process-global transport wants;
one owned by a context object is a per-context namespace, which is what
libzmq’s inproc:// actually is. Neither needs a different type.
The byte budget is remote input’s bound. A name may come from a peer,
an address or a configuration file, so its length is capped at
construction time and every entry point checks it
(docs/INVARIANTS.md). Control bytes are refused for the same reason a
name is a name: it ends up in a log line, an error message and a
comparison.
Implementations§
Source§impl<T> NameRegistry<T>
impl<T> NameRegistry<T>
Sourcepub fn new(max_name_bytes: usize) -> NameRegistry<T>
pub fn new(max_name_bytes: usize) -> NameRegistry<T>
A registry whose names may be at most max_name_bytes bytes long.
Sourcepub const fn max_name_bytes(&self) -> usize
pub const fn max_name_bytes(&self) -> usize
The byte budget names in this registry live under.
Sourcepub fn validate(&self, name: &str) -> Result<(), Error>
pub fn validate(&self, name: &str) -> Result<(), Error>
Checks name against the budget and against the control bytes.
A consumer whose own grammar forbids more than this — a separator byte, say, because the name is one field of an address — checks that itself and calls this for the rest.
Sourcepub fn bind(&self, name: &str) -> Result<UnboundedReceiver<T>, Error>
pub fn bind(&self, name: &str) -> Result<UnboundedReceiver<T>, Error>
Binds name and returns the queue of whatever is dialled to it.
Fails with Error::InvalidAddress for a name that
NameRegistry::validate refuses and with
Error::AlreadyRegistered for a name somebody already holds: one
owner per name, and the second caller is told rather than silently
displacing the first.
Sourcepub fn unbind(&self, name: &str)
pub fn unbind(&self, name: &str)
Removes name. The binding’s own drop is the caller; unbinding a name
nobody holds is not an error, because a drop cannot fail.
Sourcepub fn lookup(&self, name: &str) -> Option<UnboundedSender<T>>
pub fn lookup(&self, name: &str) -> Option<UnboundedSender<T>>
The sender for name, or None when nothing is bound there.
None is the in-process equivalent of a dial to a closed port, and
the caller reports it in its own vocabulary: this crate has no opinion
on what “nobody is listening” means to a protocol.
Sourcepub async fn wait_bound(&self, name: &str)
pub async fn wait_bound(&self, name: &str)
Resolves once name is bound, at once if it already is.
The in-process counterpart of redialling a socket: a bus is back exactly when its name is registered again, so a dialler waits on the registry rather than on a clock. Registered before the check, so a bind between the check and the wait is not missed.