Skip to main content

Governor

Struct Governor 

Source
pub struct Governor { /* private fields */ }
Expand description

The single source of parallelism in the process.

Work units acquire LeaseSets rather than being handed a thread count, which is what makes nested parallelism safe: an outer “8 entries at once” and an inner “multi-threaded zstd” both draw from this one pool, so their product can never exceed the budget.

Implementations§

Source§

impl Governor

Source

pub fn new(workers: usize, memory_limit: u64) -> Arc<Self> ⓘ

Source

pub fn from_inputs(inputs: &BudgetInputs, memory_limit: u64) -> Arc<Self> ⓘ

Source

pub fn workers(&self) -> usize

Source

pub fn memory_limit(&self) -> u64

Source

pub fn outstanding(&self) -> usize

Source

pub fn reserved_bytes(&self) -> u64

Source

pub fn acquire_many( self: &Arc<Self>, want: usize, per_worker_bytes: u64, ) -> LeaseSet

Acquires up to want workers, and the memory they need, in one call.

Grants min(want, workers_free, memory_free / per_worker_bytes), blocking only while no worker slot is free at all, and never granting fewer than one — a single over-budget worker beats no progress.

Granting the floor worker can push the reserved total past memory_limit — by less than one worker’s demand per grant, but that bound does not sum across grants. Eight concurrent callers each asking for one worker will each see cpu_free > 0, each floor to 1, and each charge per_worker_bytes, so the reserved total can reach workers × per_worker_bytes regardless of memory_limit. The memory budget therefore bounds voluntary parallelism, not a hard ceiling on reserved bytes; the hard ceiling is the worker count. That over-commitment is the price of the progress guarantee — a caller that would otherwise wait forever runs over budget instead of never running.

Acquire once. A unit takes its whole allocation in one call and does not acquire again while holding. Hold-and-wait is what deadlocks: four units each holding one lease and each blocking for a second would never progress. Getting fewer workers than asked is fine, the work runs slower; blocking for the full request would trade a deadlock for a stall.

Source

pub fn acquire(self: &Arc<Self>) -> LeaseSet

Blocks until at least one worker is available.

Source

pub fn try_acquire(self: &Arc<Self>) -> Option<LeaseSet>

Returns None immediately if the pool is full.

Source

pub fn workers_for(&self, per_worker_bytes: u64) -> usize

How many workers a codec needing per_worker_bytes could use.

A hint for sizing work before committing. It reserves nothing — two concurrent callers both get the same answer. Call Self::acquire_many to actually reserve.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.