pub struct TenantRegistry { /* private fields */ }Expand description
Tenant registry with dynamic provisioning.
Hot path: resolve() is one ArcSwap pointer load + an immutable map
read — exactly the zero-lock profile of the old frozen map. Control
plane: Self::upsert/Self::suspend/Self::resume copy-on-write a new snapshot and
swap it atomically, so onboarding a customer (or cutting off a delinquent
one) takes effect on the next request — no redeploy, no restart.
Not #[Injectable] — provide via ctx.provide(TenantRegistry::new(...)).
Implementations§
Source§impl TenantRegistry
impl TenantRegistry
pub fn new( strategy: TenantStrategy, tenants: Vec<TenantConfig>, fallback: Option<TenantId>, ) -> Self
Sourcepub fn upsert(&self, cfg: TenantConfig)
pub fn upsert(&self, cfg: TenantConfig)
Add or replace a tenant — visible to the very next request.
Sourcepub fn suspend(&self, id: &TenantId)
pub fn suspend(&self, id: &TenantId)
Suspend a tenant: resolve() returns None → guards reject with 401.
Deliberately does NOT fall through to the fallback tenant — a
suspended customer must not silently ride the shared pool.
pub fn resume(&self, id: &TenantId)
Sourcepub fn resolve(&self, headers: &HeaderMap) -> Option<Arc<TenantConfig>>
pub fn resolve(&self, headers: &HeaderMap) -> Option<Arc<TenantConfig>>
Resolve the request’s tenant. Called once per request by the boundary.
One atomic snapshot load + immutable map reads — zero locks.
Unknown IDs resolve to the fallback (a typo’d header cannot select an
unconfigured tenant); suspended IDs resolve to None outright.
pub fn get(&self, id: &TenantId) -> Option<Arc<TenantConfig>>
Sourcepub fn resolve_by_id(&self, id: &str) -> Option<Arc<TenantConfig>>
pub fn resolve_by_id(&self, id: &str) -> Option<Arc<TenantConfig>>
Resolve a tenant by its raw id — the non-HTTP twin of
resolve, used by the consumer mesh where the id
rides a message envelope instead of a header. Same semantics:
suspended → None outright (a suspended tenant’s queued events
must stop processing, exactly like its HTTP traffic). Unknown ids get
no fallback: an envelope names its tenant explicitly, and falling
back would process data under the wrong tenant.
Auto Trait Implementations§
impl !Freeze for TenantRegistry
impl RefUnwindSafe for TenantRegistry
impl Send for TenantRegistry
impl Sync for TenantRegistry
impl Unpin for TenantRegistry
impl UnsafeUnpin for TenantRegistry
impl UnwindSafe for TenantRegistry
Blanket Implementations§
Source§impl<T> AggregateExpressionMethods for T
impl<T> AggregateExpressionMethods for T
Source§fn aggregate_distinct(self) -> Self::Outputwhere
Self: DistinctDsl,
fn aggregate_distinct(self) -> Self::Outputwhere
Self: DistinctDsl,
DISTINCT modifier for aggregate functions Read moreSource§fn aggregate_all(self) -> Self::Outputwhere
Self: AllDsl,
fn aggregate_all(self) -> Self::Outputwhere
Self: AllDsl,
ALL modifier for aggregate functions Read moreSource§fn aggregate_filter<P>(self, f: P) -> Self::Output
fn aggregate_filter<P>(self, f: P) -> Self::Output
Source§fn aggregate_order<O>(self, o: O) -> Self::Outputwhere
Self: OrderAggregateDsl<O>,
fn aggregate_order<O>(self, o: O) -> Self::Outputwhere
Self: OrderAggregateDsl<O>,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<T> FutureExt for T
impl<T> FutureExt for T
Source§fn with_context(self, otel_cx: Context) -> WithContext<Self>
fn with_context(self, otel_cx: Context) -> WithContext<Self>
Source§fn with_current_context(self) -> WithContext<Self>
fn with_current_context(self) -> WithContext<Self>
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::RequestSource§impl<T> IntoSql for T
impl<T> IntoSql for T
Source§fn into_sql<T>(self) -> Self::Expression
fn into_sql<T>(self) -> Self::Expression
self to an expression for Diesel’s query builder. Read moreSource§fn as_sql<'a, T>(&'a self) -> <&'a Self as AsExpression<T>>::Expression
fn as_sql<'a, T>(&'a self) -> <&'a Self as AsExpression<T>>::Expression
&self to an expression for Diesel’s query builder. Read more