Skip to main content

NamespaceStore

Trait NamespaceStore 

Source
pub trait NamespaceStore:
    Send
    + Sync
    + 'static {
    // Required methods
    fn register_namespace<'life0, 'life1, 'async_trait>(
        &'life0 self,
        name: &'life1 str,
        origin: NamespaceOrigin,
    ) -> Pin<Box<dyn Future<Output = Result<MintOutcome, StoreError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn put_namespace<'life0, 'async_trait>(
        &'life0 self,
        record: NamespaceRecord,
    ) -> Pin<Box<dyn Future<Output = Result<MintOutcome, StoreError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait;
    fn list_namespaces<'life0, 'async_trait>(
        &'life0 self,
    ) -> Pin<Box<dyn Future<Output = Result<Vec<NamespaceRecord>, StoreError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait;
    fn get_namespace<'life0, 'life1, 'async_trait>(
        &'life0 self,
        name: &'life1 str,
    ) -> Pin<Box<dyn Future<Output = Result<Option<NamespaceRecord>, StoreError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn set_namespace_placement<'life0, 'life1, 'async_trait>(
        &'life0 self,
        name: &'life1 str,
        placement: NamespacePlacement,
    ) -> Pin<Box<dyn Future<Output = Result<Option<()>, StoreError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn deprecate_namespace<'life0, 'life1, 'async_trait>(
        &'life0 self,
        name: &'life1 str,
    ) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
}
Expand description

Durable persistence contract for the minted-on-use namespace registry.

A sibling to crate::PackageStore, deliberately not folded into it: the registry’s durability is stronger (it must survive owner-node death via the quorum-replicated path, where packages use a plain local write), and its create-if-absent / value-CAS / reconcile-on-conflict mint semantics have no analogue in the package store’s unconditional put. Single-node / local backends satisfy the contract with a plain local upsert (no quorum to reach); the haematite backend implements the real quorum-replicated path.

Required Methods§

Source

fn register_namespace<'life0, 'life1, 'async_trait>( &'life0 self, name: &'life1 str, origin: NamespaceOrigin, ) -> Pin<Box<dyn Future<Output = Result<MintOutcome, StoreError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Idempotent minted-on-use upsert.

Create-if-absent: if no record exists for name, one is minted with the given origin. If a record already exists, its last_seen is refreshed (value-CAS touch) and origin is left untouched. A concurrent racer that wrote an equivalent record first is reconciled as success — the mint is idempotent and lock-free.

Returns whether this call CREATED the record (drives the “loud created” event) versus touched an existing one.

§Errors

Returns StoreError::NotOwner if a quorum write is fenced because this node is not the current owner of the record’s shard, or StoreError::Backend / StoreError::Serialization on a backend or codec failure.

Source

fn put_namespace<'life0, 'async_trait>( &'life0 self, record: NamespaceRecord, ) -> Pin<Box<dyn Future<Output = Result<MintOutcome, StoreError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Explicit upsert (POST /namespaces).

The same idempotent upsert as NamespaceStore::register_namespace, but carrying a caller-supplied record (typically NamespaceOrigin::Explicit with an initial config). Idempotent on an existing name: an already-present record is reconciled as success rather than overwritten wholesale.

§Errors

As NamespaceStore::register_namespace.

Source

fn list_namespaces<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Vec<NamespaceRecord>, StoreError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Returns the live durable set, ascending by created_at (ties broken by name).

Backs GET /namespaces. The returned set is the raw durable truth; grant-filtering happens at the API layer, never here.

§Errors

Returns StoreError::Backend / StoreError::Serialization on a backend or codec failure.

Source

fn get_namespace<'life0, 'life1, 'async_trait>( &'life0 self, name: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<Option<NamespaceRecord>, StoreError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Looks up a single namespace by name.

The existence probe for the closed auto-create policy and the resolver’s existence anchor. Returns None for an absent name (never an error).

§Errors

Returns StoreError::Backend / StoreError::Serialization on a backend or codec failure.

Source

fn set_namespace_placement<'life0, 'life1, 'async_trait>( &'life0 self, name: &'life1 str, placement: NamespacePlacement, ) -> Pin<Box<dyn Future<Output = Result<Option<()>, StoreError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Idempotent quorum-CAS update of an existing namespace’s placement directive (Control-Plane Phase 2, P2-P2).

Read-modify-writes ONLY the NamespaceRecord::placement field of an existing record, leaving origin, created_at, config, and state untouched; last_seen is refreshed as the operation is a fresh reference. It is the same value-CAS upsert every registry mutation uses, so a concurrent racer that wrote an equivalent placement first is reconciled as success (idempotent, lock-free). Setting placement to the value the record already holds is a successful no-op.

Returns Ok(None) when no record exists for name (placement targets an already-minted namespace; the caller surfaces a not-found rather than minting a row here), or Ok(Some(())) when the placement was durably set.

§Errors

Returns StoreError::NotOwner if a quorum write is fenced because this node is not the current owner of the record’s shard, or StoreError::Backend / StoreError::Serialization on a backend or codec failure.

Source

fn deprecate_namespace<'life0, 'life1, 'async_trait>( &'life0 self, name: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Transitions a namespace from NamespaceState::Active to NamespaceState::Deprecated (deprecate-before-delete).

Idempotent: deprecating an already-deprecated namespace, or one with no registry row, is a no-op rather than an error. Deprecation never strands durable history.

§Errors

Returns StoreError::NotOwner if a quorum write is fenced, or StoreError::Backend / StoreError::Serialization on a backend or codec failure.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§