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
impl Registry
Sourcepub fn register_with_control_ops(
&self,
manifest: ModuleManifest,
negotiated_ver: u8,
connection_id: ConnectionId,
control_ops: Vec<String>,
) -> Result<ModuleRegistration, RegistryError>
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.
Sourcepub fn register_unpublished_with_control_ops(
&self,
manifest: ModuleManifest,
negotiated_ver: u8,
connection_id: ConnectionId,
control_ops: Vec<String>,
) -> Result<ModuleRegistration, RegistryError>
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.
Sourcepub fn register_candidate_with_control_ops(
&self,
manifest: ModuleManifest,
negotiated_ver: u8,
connection_id: ConnectionId,
control_ops: Vec<String>,
) -> Result<ModuleRegistration, RegistryError>
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.
Sourcepub fn register_unpublished_candidate_with_control_ops(
&self,
manifest: ModuleManifest,
negotiated_ver: u8,
connection_id: ConnectionId,
control_ops: Vec<String>,
) -> Result<ModuleRegistration, RegistryError>
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.
Sourcepub fn publish_registration(
&self,
connection_id: ConnectionId,
) -> Result<bool, RegistryError>
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.
Sourcepub fn promote_candidate(
&self,
module_id: &str,
) -> Result<Option<RegistryCutover>, RegistryError>
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.
Sourcepub fn get_module(
&self,
module_id: &str,
) -> Result<Option<ModuleRegistration>, RegistryError>
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.
Sourcepub fn get_candidate(
&self,
module_id: &str,
) -> Result<Option<ModuleRegistration>, RegistryError>
pub fn get_candidate( &self, module_id: &str, ) -> Result<Option<ModuleRegistration>, RegistryError>
The swap candidate registered for module_id, if any.
Sourcepub fn registration(
&self,
slot: RegistrationSlot<'_>,
) -> Result<Option<ModuleRegistration>, RegistryError>
pub fn registration( &self, slot: RegistrationSlot<'_>, ) -> Result<Option<ModuleRegistration>, RegistryError>
The registration held in one specific slot. See RegistrationSlot.
pub fn active_registration_count(&self) -> Result<usize, RegistryError>
Sourcepub fn list_modules(
&self,
) -> Result<(u64, Vec<ModuleRegistration>), RegistryError>
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.
Sourcepub fn list_registered_modules(
&self,
) -> Result<Vec<ModuleRegistration>, RegistryError>
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.
Sourcepub fn published_registration(
&self,
slot: RegistrationSlot<'_>,
) -> Result<Option<ModuleRegistration>, RegistryError>
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.
pub fn generation(&self) -> Result<u64, RegistryError>
Sourcepub fn get_module_by_connection(
&self,
connection_id: ConnectionId,
) -> Result<Option<ModuleRegistration>, RegistryError>
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.
Sourcepub fn replace_catalog_for_connection(
&self,
connection_id: ConnectionId,
provides: Vec<ProviderRole>,
capabilities: Option<CapabilityDeclarations>,
ready: Option<bool>,
) -> Result<Option<ModuleRegistration>, RegistryError>
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.
Sourcepub fn deregister_connection(
&self,
connection_id: ConnectionId,
) -> Result<Vec<ModuleRegistration>, RegistryError>
pub fn deregister_connection( &self, connection_id: ConnectionId, ) -> Result<Vec<ModuleRegistration>, RegistryError>
Deregister every module owned by a dropped connection, in any slot.