pub struct MemoryGovernor { /* private fields */ }Expand description
The central memory governor.
Thread-safe: global, database, and tenant counters use atomics.
The budget map itself is behind an RwLock; reads (common) take a shared
lock, writes (rare — only when quotas change) take an exclusive lock.
Implementations§
Source§impl MemoryGovernor
impl MemoryGovernor
Sourcepub fn reserve(
self: &Arc<Self>,
engine: EngineId,
bytes: usize,
) -> Result<BudgetGuard>
pub fn reserve( self: &Arc<Self>, engine: EngineId, bytes: usize, ) -> Result<BudgetGuard>
Reserve bytes for engine and return a BudgetGuard that releases
them on drop.
§Errors
Returns MemError::BudgetExhausted or MemError::GlobalCeilingExceeded
if the reservation would exceed any configured limit. Returns
MemError::UnknownEngine if engine is not registered.
Source§impl MemoryGovernor
impl MemoryGovernor
Sourcepub fn new(config: GovernorConfig) -> Result<Self>
pub fn new(config: GovernorConfig) -> Result<Self>
Create a new governor with the given configuration.
Sourcepub fn set_database_budget(&self, db: DatabaseId, max_bytes: usize)
pub fn set_database_budget(&self, db: DatabaseId, max_bytes: usize)
Install or replace the memory ceiling for a database.
Called by the catalog apply path when ALTER DATABASE … SET QUOTA is
executed. Takes effect for all subsequent try_reserve calls; in-flight
tokens already issued are not recalled.
Sourcepub fn clear_database_budget(&self, db: DatabaseId)
pub fn clear_database_budget(&self, db: DatabaseId)
Remove the per-database budget ceiling, making that database uncapped.
Sourcepub fn set_tenant_budget(
&self,
db: DatabaseId,
tenant: TenantId,
max_bytes: usize,
)
pub fn set_tenant_budget( &self, db: DatabaseId, tenant: TenantId, max_bytes: usize, )
Install or replace the memory ceiling for a tenant within a database.
Sourcepub fn clear_tenant_budget(&self, db: DatabaseId, tenant: TenantId)
pub fn clear_tenant_budget(&self, db: DatabaseId, tenant: TenantId)
Remove the per-tenant budget ceiling.
Sourcepub fn try_reserve(
&self,
db: DatabaseId,
tenant: TenantId,
engine: EngineId,
size: usize,
) -> Result<ReservationToken>
pub fn try_reserve( &self, db: DatabaseId, tenant: TenantId, engine: EngineId, size: usize, ) -> Result<ReservationToken>
Reserve size bytes for the given (database, tenant, engine) triple.
Check order: global → database → tenant → engine (largest scope first, to fail fast and avoid partial increments at deep levels).
On any failure the function rolls back any partial increments already
applied at higher layers and returns an error describing the exhausted
layer. On success, returns a ReservationToken whose Drop
implementation releases all four layers.
Databases or tenants without a configured budget are skipped (uncapped).
Engines without a configured budget return MemError::UnknownEngine.
Sourcepub fn release(&self, engine: EngineId, size: usize)
pub fn release(&self, engine: EngineId, size: usize)
Release size bytes back to the given engine’s budget.
This method only releases the engine-layer counter; it exists for
legacy compatibility with code that uses [BudgetGuard] rather than
ReservationToken. New code should hold a ReservationToken and let
drop handle all four layers.
Sourcepub fn budget(&self, engine: EngineId) -> Option<&Budget>
pub fn budget(&self, engine: EngineId) -> Option<&Budget>
Get the budget for a specific engine.
Sourcepub fn global_ceiling(&self) -> usize
pub fn global_ceiling(&self) -> usize
Get the global ceiling.
Sourcepub fn total_allocated(&self) -> usize
pub fn total_allocated(&self) -> usize
Total memory allocated across all engines (engine-layer sum).
Sourcepub fn total_over_release_count(&self) -> usize
pub fn total_over_release_count(&self) -> usize
Total number of over-release events observed across all
per-engine budgets. A non-zero value signals at least one
call-site is releasing more bytes than it reserved — the
“memory release exceeds allocation” warning class. Per-engine
allocated() saturates to zero on over-release, so this
counter is the only post-hoc observable for the bug.
Sourcepub fn global_utilization_percent(&self) -> u8
pub fn global_utilization_percent(&self) -> u8
Global utilization as a percentage (0-100). Computed in u128 so a
corrupted engine-layer sum clamps to 100 % instead of overflowing.
Sourcepub fn engine_pressure(&self, engine: EngineId) -> PressureLevel
pub fn engine_pressure(&self, engine: EngineId) -> PressureLevel
Current pressure level for a specific engine.
Sourcepub fn global_pressure(&self) -> PressureLevel
pub fn global_pressure(&self) -> PressureLevel
Current global pressure level.
Sourcepub fn worst_engine_pressure(&self) -> PressureLevel
pub fn worst_engine_pressure(&self) -> PressureLevel
Worst-case (highest) pressure level across every engine that has a
configured budget. Cheap: iterates the in-memory budget map and
allocates nothing — meant to be called once per Data-Plane core-loop
tick, unlike snapshot which materialises a Vec.
Returns Normal when no engine budgets are configured.
Sourcepub fn set_thresholds(&mut self, thresholds: PressureThresholds)
pub fn set_thresholds(&mut self, thresholds: PressureThresholds)
Set custom pressure thresholds.
Sourcepub fn snapshot(&self) -> Vec<EngineSnapshot>
pub fn snapshot(&self) -> Vec<EngineSnapshot>
Snapshot of all engine budget states (for metrics/debugging).
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for MemoryGovernor
impl RefUnwindSafe for MemoryGovernor
impl Send for MemoryGovernor
impl Sync for MemoryGovernor
impl Unpin for MemoryGovernor
impl UnsafeUnpin for MemoryGovernor
impl UnwindSafe for MemoryGovernor
Blanket Implementations§
Source§impl<T> ArchivePointee for T
impl<T> ArchivePointee for T
Source§type ArchivedMetadata = ()
type ArchivedMetadata = ()
Source§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
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> LayoutRaw for T
impl<T> LayoutRaw for T
Source§fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>
fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>
Source§impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
Source§unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool
unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool
Source§fn resolve_niched(out: Place<NichedOption<T, N1>>)
fn resolve_niched(out: Place<NichedOption<T, N1>>)
out indicating that a T is niched.Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.