tensor_wasm_tenant/lib.rs
1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2026 Craton Software Company
3//! Multi-tenant CUDA context management for Craton TensorWasm.
4//!
5//! This crate owns the per-tenant runtime handle ([`TenantContext`]) and the
6//! concurrent registry that maps a [`tensor_wasm_core::types::TenantId`] to it
7//! ([`TenantRegistry`]). The registry also decides between MPS-backed shared
8//! contexts and per-tenant `cuCtxCreate` fallback via a filesystem probe — see
9//! `docs/MPS-SETUP.md` for daemon configuration and `SECURITY.md` for the
10//! threat model that motivates the [`IsolationKind`] taxonomy.
11//!
12//! # Quick start
13//!
14//! Two distinct capability primitives:
15//!
16//! * [`TenantCapability`] — minted per-tenant by
17//! [`TenantRegistry::register_with_capability`], required to drive that
18//! tenant's quota counters (`consume_bytes_with_capability` /
19//! `release_bytes_with_capability`). Holding an `Arc<TenantContext>` for
20//! tenant A grants no power to mutate tenant B's accounting.
21//! * [`RegistryAdminCapability`] — minted once by [`TenantRegistry::new`],
22//! required to invoke registry-wide admin operations
23//! ([`TenantRegistry::get`], [`TenantRegistry::unregister`],
24//! [`TenantRegistry::tenants`], [`TenantRegistry::len`]). Without it, any
25//! holder of an `Arc<TenantRegistry>` could enumerate or evict tenants.
26//!
27//! ```
28//! # #[cfg(not(feature = "cuda"))]
29//! # fn main() {
30//! use tensor_wasm_core::types::TenantId;
31//! use tensor_wasm_tenant::{TenantContext, TenantRegistry};
32//!
33//! let (reg, admin_cap) = TenantRegistry::new();
34//! let (ctx, tenant_cap) = reg
35//! .register_with_capability(TenantContext::builder(TenantId(1)).build())
36//! .unwrap();
37//! ctx.consume_bytes_with_capability(&tenant_cap, 4096).unwrap();
38//! assert_eq!(ctx.bytes_in_use(), 4096);
39//! // Admin cap is required to look the tenant up again by id.
40//! assert!(reg.get(TenantId(1), &admin_cap).is_some());
41//! # }
42//! # #[cfg(feature = "cuda")]
43//! # fn main() {}
44//! ```
45#![deny(missing_docs)]
46
47pub mod context;
48pub mod registry;
49
50pub use context::{
51 isolation_downgrade_count, IsolationKind, RateLimited, TenantCapability, TenantContext,
52 TenantContextBuilder,
53};
54pub use registry::{
55 MpsDecision, RegistryAdminCapability, RegistryError, TenantRegistry, MPS_CONTROL_PATH,
56 MPS_PIPE_DIRECTORY_ENV,
57};