Skip to main content

NameRegistry

Struct NameRegistry 

Source
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>

Source

pub fn new(max_name_bytes: usize) -> NameRegistry<T>

A registry whose names may be at most max_name_bytes bytes long.

Source

pub const fn max_name_bytes(&self) -> usize

The byte budget names in this registry live under.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Trait Implementations§

Source§

impl<T> Debug for NameRegistry<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.