Skip to content

cloacina-python::registration_scope

Rust

Thread-local “who is importing right now” slot (CLOACI-T-0921).

crate::runtime_scope::ScopedRuntime tells Python decorators which Runtime to register into. This is its tenancy counterpart: it tells them whose registration this is, so the process-global Python registries (GRAPH_EXECUTORS, ACCUMULATOR_REGISTRY) can be keyed by (tenant, package, name) instead of a bare name.

Without it, two tenants each shipping a graph called pipeline share one executor slot and the second import silently wins for both — the Python-side form of the same doctrine breach CLOACI-T-0921 fixes in EndpointRegistry.

The loader installs a ScopedRegistration around each package import. Unscoped registration (embedded use, cloaca imported directly in a REPL, unit tests) yields the default all-None scope, which behaves exactly as the pre-T-0921 bare-name registry did.

pub

Derives: Debug, Clone, Default, PartialEq, Eq, Hash

Identity of the package whose import is currently running on this thread.

None fields mean “unknown / not packaged” — the embedded and test paths.

Name Type Description
tenant_id Option<String>
package Option<String>

pub

fn new(tenant_id: Option<&str>, package: Option<&str>) -> Self
Source
pub fn new(tenant_id: Option<&str>, package: Option<&str>) -> Self {
Self {
tenant_id: tenant_id.map(|s| s.to_string()),
package: package.map(|s| s.to_string()),
}
}

pub

fn unscoped() -> Self

The unscoped (embedded / direct-import / test) identity.

Source
pub fn unscoped() -> Self {
Self::default()
}

pub

fn is_unscoped(&self) -> bool

True when neither tenant nor package is known.

Source
pub fn is_unscoped(&self) -> bool {
self.tenant_id.is_none() && self.package.is_none()
}

pub

RAII guard installing a RegistrationScope for the duration of an import.

Unlike crate::runtime_scope::ScopedRuntime this nests: the previous scope is saved and restored on drop, so a package import that transitively triggers another scoped import cannot strand the outer scope.

pub

fn new(scope: RegistrationScope) -> Self
Source
pub fn new(scope: RegistrationScope) -> Self {
let previous = CURRENT_SCOPE.with(|slot| slot.replace(scope));
Self { previous }
}

pub

fn for_package(tenant_id: Option<&str>, package: Option<&str>) -> Self

Convenience for the loader paths, which hold &str tenant/package.

Source
pub fn for_package(tenant_id: Option<&str>, package: Option<&str>) -> Self {
Self::new(RegistrationScope::new(tenant_id, package))
}

pub

fn current_registration_scope() -> RegistrationScope

The registration scope installed on this thread (all-None if unscoped).

Source
pub fn current_registration_scope() -> RegistrationScope {
CURRENT_SCOPE.with(|slot| slot.borrow().clone())
}