pub struct BackPressure { /* private fields */ }Expand description
A back-pressure semaphore plus a live-counter for observability.
The semaphore itself lives behind an Arc<BackPressureInner> so
multiple BackPressure clones share the same permit pool — this is
what makes the cap process-wide rather than per-instance. The
optional per-call deadline lives on the clone (not inside the
Arc) so two instances pulling from the same shared pool can each
carry their own deadline without racing on a shared Mutex.
Implementations§
Source§impl BackPressure
impl BackPressure
Sourcepub fn with_deadline_hint(self, deadline: Option<Instant>) -> Self
pub fn with_deadline_hint(self, deadline: Option<Instant>) -> Self
Attach a per-invocation deadline to this BackPressure clone.
The deadline is consulted on every acquire (both acquire and
acquire_borrowed):
- If
Instant::now() >= deadline, the acquire returnsBackPressureError::DeadlineElapsedwithout awaiting. - If
Instant::now() >= deadline - DEADLINE_NEAR_WINDOW, the acquire returnsBackPressureError::DeadlineNear— the in-flight cohort is permitted to complete but no new permits are issued. - Otherwise the acquire behaves exactly as before (
Nonedeadline = unchanged behaviour).
Builder method: consumes self and returns a new clone with
the deadline installed. The underlying semaphore is shared via
Arc so two clones that pull from the same pool can each
carry their own deadline. Passing None is the documented
“no deadline” knob — equivalent to a fresh BackPressure
constructed via BackPressure::with_cap.
See crate::scheduler::SchedulerContext for the matching
cooperative-yield query path: the executor builds both from
the same Instant so the guest’s yield() verdicts and the
host’s acquire decisions agree on when the deadline trips.
Sourcepub fn deadline_hint(&self) -> Option<Instant>
pub fn deadline_hint(&self) -> Option<Instant>
Borrow the per-clone deadline, if any. Mirrors
BackPressure::with_deadline_hint — useful for tests and
observability paths that want to confirm the executor wired the
deadline through.
Sourcepub async fn acquire(&self) -> DispatchPermit
pub async fn acquire(&self) -> DispatchPermit
Acquire one permit, awaiting back-pressure if necessary.
Returns an owned permit ('static) suitable for callers that move
the permit across tokio::spawn boundaries (tests, benches, any
future fan-out path). Each call clones the inner Arc<Semaphore>.
On the non-spawning production hot path, prefer
BackPressure::acquire_borrowed which avoids that clone.
Deadline-hint-unaware: this method returns an unconditional
permit and never refuses on deadline grounds. Callers that
need the deadline-aware rejection path must use
BackPressure::try_acquire_with_deadline or
BackPressure::acquire_borrowed; this method is kept on the
pre-deadline surface for tests / benches that pre-date the
deadline plumbing and would otherwise need a typed-error
rewrite. (The production launch_impl_async path uses
acquire_borrowed, which DOES honour the deadline.)
Sourcepub async fn acquire_with_deadline(
&self,
) -> Result<DispatchPermit, BackPressureError>
pub async fn acquire_with_deadline( &self, ) -> Result<DispatchPermit, BackPressureError>
Deadline-aware counterpart to BackPressure::acquire that
returns the typed BackPressureError on rejection.
On the no-deadline path this behaves exactly like
BackPressure::acquire but with the typed error surface.
When a deadline is configured (via
BackPressure::with_deadline_hint):
- Past the deadline: returns
Err(DeadlineElapsed). - Within
DEADLINE_NEAR_WINDOWof the deadline: returnsErr(DeadlineNear)— in-flight acquires already issued are not affected (they hold their permits to completion); only new acquires are refused, allowing the cohort to drain. - More than
DEADLINE_NEAR_WINDOWaway: behaves asBackPressure::acquire(awaits a permit).
Sourcepub fn try_acquire_with_deadline(
&self,
) -> Result<DispatchPermit, BackPressureError>
pub fn try_acquire_with_deadline( &self, ) -> Result<DispatchPermit, BackPressureError>
Non-blocking variant of BackPressure::acquire_with_deadline.
Returns Err(Saturated) when no permit is immediately
available and the deadline does not pre-empt the saturation
path with a more specific code.
Sourcepub async fn acquire_borrowed(
&self,
) -> Result<BorrowedDispatchPermit<'_>, AbiError>
pub async fn acquire_borrowed( &self, ) -> Result<BorrowedDispatchPermit<'_>, AbiError>
Acquire one permit, awaiting back-pressure if necessary.
Returns a borrowed permit whose lifetime is tied to &self. This
avoids the Arc<Semaphore> clone that BackPressure::acquire
performs and is the right choice for callers that hold the permit
only within the current async scope (no tokio::spawn). The
production launch_impl_async host-function path runs inside a
wasmtime async fiber that never spawns, so it uses this variant.
§Cap-0 / saturated semantics
A cap of 0 is a “no permits, ever” sentinel: the semaphore was
constructed with zero permits and none will ever be released
because nothing can acquire to release. Awaiting Semaphore::acquire
in that state parks the caller forever — a footgun, because guests
observing back-pressure should see QuotaExceeded rather than
hang. We therefore probe with try_acquire first: if it fails
AND the configured cap is 0, we return AbiError::QuotaExceeded
rather than awaiting. For caps > 0 we fall through to the standard
async acquire (permits will eventually return as in-flight
dispatches drop their permits).
Sourcepub fn try_acquire(&self) -> Option<DispatchPermit>
pub fn try_acquire(&self) -> Option<DispatchPermit>
Try to acquire a permit without awaiting. Returns None under load.
Sourcepub fn max_concurrent(&self) -> usize
pub fn max_concurrent(&self) -> usize
Maximum concurrent dispatches.
Trait Implementations§
Source§impl Clone for BackPressure
impl Clone for BackPressure
Source§fn clone(&self) -> BackPressure
fn clone(&self) -> BackPressure
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreAuto Trait Implementations§
impl !RefUnwindSafe for BackPressure
impl !UnwindSafe for BackPressure
impl Freeze for BackPressure
impl Send for BackPressure
impl Sync for BackPressure
impl Unpin for BackPressure
impl UnsafeUnpin for BackPressure
Blanket Implementations§
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> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
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> 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