Struct K2KBroker
pub struct K2KBroker {
config: K2KConfig,
tenants: RwLock<RawRwLock, HashMap<u64, Arc<K2KSubBroker>>>,
kernel_tenant: RwLock<RawRwLock, HashMap<KernelId, u64>>,
registry: Arc<TenantRegistry>,
receipts: RwLock<RawRwLock, HashMap<MessageId, DeliveryReceipt>>,
message_counter: Atomic<u64>,
cross_tenant_rejections: Atomic<u64>,
}Expand description
K2K message broker with per-tenant isolation.
Internally holds a HashMap<TenantId, K2KSubBroker>. Single-tenant
deployments see exactly one entry (for UNSPECIFIED_TENANT = 0); the
only overhead over the legacy broker is one additional HashMap lookup
per send (~20 ns).
Fields§
§config: K2KConfig§tenants: RwLock<RawRwLock, HashMap<u64, Arc<K2KSubBroker>>>§kernel_tenant: RwLock<RawRwLock, HashMap<KernelId, u64>>§registry: Arc<TenantRegistry>§receipts: RwLock<RawRwLock, HashMap<MessageId, DeliveryReceipt>>§message_counter: Atomic<u64>§cross_tenant_rejections: Atomic<u64>Implementations§
§impl K2KBroker
impl K2KBroker
pub fn new(config: K2KConfig) -> Arc<K2KBroker> ⓘ
pub fn new(config: K2KConfig) -> Arc<K2KBroker> ⓘ
Create a new K2K broker with an empty TenantRegistry.
pub fn with_registry(
config: K2KConfig,
registry: Arc<TenantRegistry>,
) -> Arc<K2KBroker> ⓘ
pub fn with_registry( config: K2KConfig, registry: Arc<TenantRegistry>, ) -> Arc<K2KBroker> ⓘ
Create a new K2K broker sharing the given TenantRegistry.
This is the multi-tenant constructor: wire up the registry (with its
audit sink) once, then pass the Arc to every broker that should
enforce against it.
pub fn registry(&self) -> &Arc<TenantRegistry> ⓘ
pub fn registry(&self) -> &Arc<TenantRegistry> ⓘ
Shared reference to the tenant registry.
pub fn tenant_count(&self) -> usize
pub fn tenant_count(&self) -> usize
Total number of active tenant sub-brokers.
pub fn sub_broker(&self, tenant_id: u64) -> Option<Arc<K2KSubBroker>>
pub fn sub_broker(&self, tenant_id: u64) -> Option<Arc<K2KSubBroker>>
Get the sub-broker for a tenant, if it exists.
pub fn register(self: &Arc<K2KBroker>, kernel_id: KernelId) -> K2KEndpoint
pub fn register(self: &Arc<K2KBroker>, kernel_id: KernelId) -> K2KEndpoint
Register a kernel without a tenant / audit tag (legacy API).
The kernel is placed in the unspecified-tenant sub-broker
(UNSPECIFIED_TENANT = 0). This is the backward-compatible entry
point for single-tenant deployments — existing callers don’t need to
change anything.
pub fn register_tenant(
self: &Arc<K2KBroker>,
tenant_id: u64,
audit_tag: AuditTag,
kernel_id: KernelId,
) -> K2KEndpoint
pub fn register_tenant( self: &Arc<K2KBroker>, tenant_id: u64, audit_tag: AuditTag, kernel_id: KernelId, ) -> K2KEndpoint
Register a kernel into the given tenant’s sub-broker, stamping the
AuditTag that will be applied to outgoing messages from this
kernel.
If the tenant doesn’t yet have a sub-broker, one is created lazily. If the kernel was previously registered under a different tenant, the old registration is replaced (the old mpsc sender is dropped — in-flight messages to the old registration are lost). This preserves the invariant that a kernel belongs to exactly one tenant.
pub fn unregister(&self, kernel_id: &KernelId)
pub fn unregister(&self, kernel_id: &KernelId)
Unregister a kernel from whichever tenant it belongs to.
pub fn is_registered(&self, kernel_id: &KernelId) -> bool
pub fn is_registered(&self, kernel_id: &KernelId) -> bool
Check if a kernel is registered (under any tenant).
pub fn tenant_of(&self, kernel_id: &KernelId) -> Option<u64>
pub fn tenant_of(&self, kernel_id: &KernelId) -> Option<u64>
Get the tenant this kernel belongs to, if registered.
pub fn registered_kernels(&self) -> Vec<KernelId>
pub fn registered_kernels(&self) -> Vec<KernelId>
All registered kernel IDs (across every tenant).
pub fn registered_kernels_for(&self, tenant_id: u64) -> Vec<KernelId>
pub fn registered_kernels_for(&self, tenant_id: u64) -> Vec<KernelId>
Kernel IDs registered under a specific tenant.
pub async fn send(
&self,
source: KernelId,
destination: KernelId,
envelope: MessageEnvelope,
) -> Result<DeliveryReceipt, RingKernelError>
pub async fn send( &self, source: KernelId, destination: KernelId, envelope: MessageEnvelope, ) -> Result<DeliveryReceipt, RingKernelError>
Send a message from one kernel to another (normal priority).
Enforces tenant isolation: the sender’s and destination’s tenants
must match, or the send is rejected with
crate::error::RingKernelError::TenantMismatch and an audit event
is emitted.
pub async fn send_priority(
&self,
source: KernelId,
destination: KernelId,
envelope: MessageEnvelope,
priority: u8,
) -> Result<DeliveryReceipt, RingKernelError>
pub async fn send_priority( &self, source: KernelId, destination: KernelId, envelope: MessageEnvelope, priority: u8, ) -> Result<DeliveryReceipt, RingKernelError>
Send a priority message.
pub async fn send_with_audit(
&self,
source: KernelId,
destination: KernelId,
envelope: MessageEnvelope,
audit_tag: AuditTag,
) -> Result<DeliveryReceipt, RingKernelError>
pub async fn send_with_audit( &self, source: KernelId, destination: KernelId, envelope: MessageEnvelope, audit_tag: AuditTag, ) -> Result<DeliveryReceipt, RingKernelError>
Send a message stamped with an explicit audit tag (overriding the registration-time tag).
Useful for the same kernel participating in multiple engagements — e.g. a shared report-generation kernel that should bill different engagements depending on which request it’s serving.
pub fn add_route(&self, destination: KernelId, next_hop: KernelId)
pub fn add_route(&self, destination: KernelId, next_hop: KernelId)
Add an indirect route inside the unspecified-tenant sub-broker (legacy API — single-tenant callers should use this).
pub fn add_route_in(
&self,
tenant_id: u64,
destination: KernelId,
next_hop: KernelId,
)
pub fn add_route_in( &self, tenant_id: u64, destination: KernelId, next_hop: KernelId, )
Add an indirect route inside a specific tenant’s sub-broker.
pub fn remove_route(&self, destination: &KernelId)
pub fn remove_route(&self, destination: &KernelId)
Remove an indirect route from the unspecified-tenant sub-broker.
pub fn remove_route_in(&self, tenant_id: u64, destination: &KernelId)
pub fn remove_route_in(&self, tenant_id: u64, destination: &KernelId)
Remove an indirect route from a specific tenant’s sub-broker.
pub fn tenant_stats(&self, tenant_id: u64) -> Option<TenantStats>
pub fn tenant_stats(&self, tenant_id: u64) -> Option<TenantStats>
Get per-tenant stats (useful for billing / dashboards).
pub fn get_receipt(&self, message_id: &MessageId) -> Option<DeliveryReceipt>
pub fn get_receipt(&self, message_id: &MessageId) -> Option<DeliveryReceipt>
Get delivery receipt for a message.
Auto Trait Implementations§
impl !Freeze for K2KBroker
impl !RefUnwindSafe for K2KBroker
impl !UnwindSafe for K2KBroker
impl Send for K2KBroker
impl Sync for K2KBroker
impl Unpin for K2KBroker
impl UnsafeUnpin for K2KBroker
Blanket Implementations§
§impl<T> ArchivePointee for T
impl<T> ArchivePointee for T
§type ArchivedMetadata = ()
type ArchivedMetadata = ()
§fn pointer_metadata(
_: &<T as ArchivePointee>::ArchivedMetadata,
) -> <T as Pointee>::Metadata
fn pointer_metadata( _: &<T as ArchivePointee>::ArchivedMetadata, ) -> <T as Pointee>::Metadata
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<F, W, T, D> Deserialize<With<T, W>, D> for F
impl<F, W, T, D> Deserialize<With<T, W>, D> for F
§fn deserialize(
&self,
deserializer: &mut D,
) -> Result<With<T, W>, <D as Fallible>::Error>
fn deserialize( &self, deserializer: &mut D, ) -> Result<With<T, W>, <D as Fallible>::Error>
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§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 more