Skip to main content

Registry

Struct Registry 

Source
pub struct Registry { /* private fields */ }
Expand description

Control-plane registry for module manifests and supervision ownership.

Duplicate active module_ids are rejected rather than replaced. Rejection is the safer v1 behavior because replacing a still-connected module could hijack in-flight routes. Stale registrations are removed by connection cleanup; a reconnect after the old connection drops can then register the same id again.

A blue/green swap is the one sanctioned way two processes hold the same id. The replacement registers into a separate candidate slot, which every by-id lookup ignores, so it stays unroutable until Registry::promote_candidate swaps it in. The old incumbent is then kept as “superseded” until its connection deregisters. Lookups keyed by connection id search all three slots, because a connection must be able to update and remove its own registration whichever slot it currently sits in.

Implementations§

Source§

impl Registry

Source

pub fn register_with_control_ops( &self, manifest: ModuleManifest, negotiated_ver: u8, connection_id: ConnectionId, control_ops: Vec<String>, ) -> Result<ModuleRegistration, RegistryError>

Register a module manifest with the module’s effective granted control op set.

The registration is published at once: it is listed by Self::list_modules and bumps the catalog generation. The HELLO path uses Self::register_unpublished_with_control_ops instead, because it still has to install the module’s forwarding endpoint.

Source

pub fn register_unpublished_with_control_ops( &self, manifest: ModuleManifest, negotiated_ver: u8, connection_id: ConnectionId, control_ops: Vec<String>, ) -> Result<ModuleRegistration, RegistryError>

Register a module manifest without listing it yet.

The registration holds its module id and is visible to every lookup except Self::list_modules (and so catalog.list) and Self::published_registration. The catalog generation does not move. Call Self::publish_registration once the module can actually be routed to; if that never becomes possible, deregistering the connection removes the entry without the catalog ever having listed it.

Source

pub fn register_candidate_with_control_ops( &self, manifest: ModuleManifest, negotiated_ver: u8, connection_id: ConnectionId, control_ops: Vec<String>, ) -> Result<ModuleRegistration, RegistryError>

Register a swap candidate for manifest.module_id into the candidate slot.

The candidate is invisible to Self::get_module, Self::list_modules and every other by-id lookup until Self::promote_candidate. An active registration for the id is not required, because the incumbent may die while the swap is open; deciding whether a candidate may register at all belongs to the caller that admits it. A second candidate for the same id is refused.

The candidate is published at once, meaning candidate-slot lookups through Self::published_registration return it immediately. The HELLO path uses Self::register_unpublished_candidate_with_control_ops instead.

Source

pub fn register_unpublished_candidate_with_control_ops( &self, manifest: ModuleManifest, negotiated_ver: u8, connection_id: ConnectionId, control_ops: Vec<String>, ) -> Result<ModuleRegistration, RegistryError>

Register a swap candidate that Self::published_registration does not return until Self::publish_registration is called for its connection. The swap supervisor reads that lookup to decide the candidate has registered, and it promotes a ready candidate straight away; promoting one whose forwarding endpoint is not installed yet would fail the cutover.

Source

pub fn publish_registration( &self, connection_id: ConnectionId, ) -> Result<bool, RegistryError>

Publish the registration connection_id holds, in whichever slot.

For an active registration this is the moment catalog.list starts listing the module, and the catalog generation advances under the same lock, so no reader can see the new generation without the module or the module without the new generation. A candidate is not listed either way; publishing it only makes it visible to Self::published_registration.

Returns false when there is nothing to publish: the connection holds no registration any more, or it was already published.

Source

pub fn promote_candidate( &self, module_id: &str, ) -> Result<Option<RegistryCutover>, RegistryError>

Move the candidate for module_id into the active slot and demote the previous active registration, in one registry critical section.

Returns Ok(None) when there is no candidate to promote. Bumps the catalog generation, because the listed registration for the id changed.

Source

pub fn get_module( &self, module_id: &str, ) -> Result<Option<ModuleRegistration>, RegistryError>

The ACTIVE registration for module_id. Candidates and superseded incumbents are never returned: this is the lookup routing decisions use.

Source

pub fn get_candidate( &self, module_id: &str, ) -> Result<Option<ModuleRegistration>, RegistryError>

The swap candidate registered for module_id, if any.

Source

pub fn registration( &self, slot: RegistrationSlot<'_>, ) -> Result<Option<ModuleRegistration>, RegistryError>

The registration held in one specific slot. See RegistrationSlot.

Source

pub fn active_registration_count(&self) -> Result<usize, RegistryError>

Source

pub fn list_modules( &self, ) -> Result<(u64, Vec<ModuleRegistration>), RegistryError>

The catalog generation and the active registrations catalog.list shows. Unpublished registrations (see Self::register_unpublished_with_control_ops) are left out.

Source

pub fn list_registered_modules( &self, ) -> Result<Vec<ModuleRegistration>, RegistryError>

Every active registration, including unpublished ones.

For the capability evaluator and the capability deny census, which count a module as soon as it has registered. Whether catalog.list shows the module yet does not change their verdicts.

Source

pub fn published_registration( &self, slot: RegistrationSlot<'_>, ) -> Result<Option<ModuleRegistration>, RegistryError>

Like Self::registration, but a registration that is not published yet is reported as absent.

Source

pub fn generation(&self) -> Result<u64, RegistryError>

Source

pub fn get_module_by_connection( &self, connection_id: ConnectionId, ) -> Result<Option<ModuleRegistration>, RegistryError>

The registration owned by connection_id, searching the active, candidate and superseded slots in that order.

Source

pub fn replace_catalog_for_connection( &self, connection_id: ConnectionId, provides: Vec<ProviderRole>, capabilities: Option<CapabilityDeclarations>, ready: Option<bool>, ) -> Result<Option<ModuleRegistration>, RegistryError>

Replace the provider role list and, when supplied, the attested capability declaration for the module owned by connection_id.

Searches every slot: a swap candidate declares itself ready through this call, and if only the active slot were searched its update would find nothing and the candidate would never become ready. Only a change to the active slot bumps the catalog generation, because only the active slot is listed, and only once that registration is published.

Source

pub fn deregister_connection( &self, connection_id: ConnectionId, ) -> Result<Vec<ModuleRegistration>, RegistryError>

Deregister every module owned by a dropped connection, in any slot.

Trait Implementations§

Source§

impl Debug for Registry

Source§

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

Formats the value using the given formatter. Read more
Source§

impl Default for Registry

Source§

fn default() -> Self

Returns the “default value” for a type. 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> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> Same for T

Source§

type Output = T

Should always be Self
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.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more