pub struct ControllerDriver { /* private fields */ }Expand description
Shared, live bridge between a pure AdaptiveController and the running
transfer backends.
The controller is &mut and deterministic; this wrapper owns it behind a
Mutex (tick is infrequent, so contention is negligible) and adds the
impure parts the controller deliberately omits: a real monotonic clock, a
live CpuSampler + RSS sampler, the manifest’s p95 object size, and the
application of each Decision to the shared AdaptiveGate (concurrency)
and — for the network backends — a rate-limiter setter + display Meter.
Both transfer paths use it identically:
- every completed/failed op calls
record_opwith its measuredOpSample; - a lightweight driver (a tokio
intervaltask for the async path, astd::threadfor the rayon path) periodically callstick, which samples CPU/RSS, advances the controller, resizes the gate, and reports the new limit/rate.
The driver is Clone (the controller, gate, sampler and the
rate/limit appliers are all shared via Arc).
Implementations§
Source§impl ControllerDriver
impl ControllerDriver
Sourcepub fn new(
policy: AdaptivePolicy,
gate: AdaptiveGate,
p95_obj_size: u64,
rate_applier: Option<Arc<dyn Fn(Option<u64>) + Send + Sync>>,
meter: Option<Arc<Meter>>,
) -> Self
pub fn new( policy: AdaptivePolicy, gate: AdaptiveGate, p95_obj_size: u64, rate_applier: Option<Arc<dyn Fn(Option<u64>) + Send + Sync>>, meter: Option<Arc<Meter>>, ) -> Self
Builds a driver around a fresh controller for policy, the shared
gate, the manifest’s p95_obj_size, an optional rate_applier (the
backend’s live rate-limit setter; None for the rate-less local store),
and an optional display meter.
Sourcepub fn record_op(&self, sample: OpSample)
pub fn record_op(&self, sample: OpSample)
Records one completed/failed op into the shared controller.
Sourcepub fn tick(&self) -> Decision
pub fn tick(&self) -> Decision
Advances the controller one interval: samples CPU/RSS, ticks with the
injected monotonic clock + p95 object size, then applies the resulting
Decision to the gate (concurrency), the rate applier (byte-rate), and
the display meter. Returns the decision for tests/inspection.
now (the monotonic clock), CPU and RSS are the driver’s only impure
inputs; all are sampled here. Determinism-sensitive tests should instead
drive tick_with, supplying every impure
input explicitly so the controller’s time- and load-dependent arms
(cooldown, re-probe, CPU guardrails) never depend on the machine’s
current clock or load.
The returned Decision is advisory (the live gate/rate/meter are
already updated as a side effect); callers may ignore it — hence not
#[must_use].
Sourcepub fn tick_with(
&self,
now: MonoTime,
cpu_pct: Option<f64>,
rss: Option<u64>,
) -> Decision
pub fn tick_with( &self, now: MonoTime, cpu_pct: Option<f64>, rss: Option<u64>, ) -> Decision
Fully time-/load-injectable sibling of tick:
advances the controller using the caller-supplied monotonic now, CPU
percentage and RSS instead of sampling the driver’s real epoch / live
CpuSampler / RSS sampler. The gate / rate / meter application step is
byte-for-byte identical to tick, so this
drives the same live wiring — only the impure inputs are injected.
This is the injectable seam (mirroring the controller’s own
tick(now, cpu, rss, …) and the crate’s injected-clock/sleeper
convention in crate::retry): it lets determinism-sensitive tests
cross the controller’s time-dependent thresholds (the 15s post-congestion
cooldown, the re-probe interval) and pin its CPU guardrails by advancing
now and fixing cpu_pct explicitly — with ZERO dependence on the
machine’s wall clock or current load (which is what made driving the live
gate trajectory flaky under parallel test load). now must be
monotonically non-decreasing across calls, exactly as epoch.elapsed()
would be; cpu_pct/rss are Some(_) to assert a guardrail or None
to skip it, exactly as the live samplers’ Options flow.
Like tick, the returned Decision is
advisory and may be ignored (the gate/rate/meter are already applied).
Trait Implementations§
Source§impl Clone for ControllerDriver
impl Clone for ControllerDriver
Source§fn clone(&self) -> ControllerDriver
fn clone(&self) -> ControllerDriver
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 ControllerDriver
impl !UnwindSafe for ControllerDriver
impl Freeze for ControllerDriver
impl Send for ControllerDriver
impl Sync for ControllerDriver
impl Unpin for ControllerDriver
impl UnsafeUnpin for ControllerDriver
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
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> FutureExt for T
impl<T> FutureExt for T
Source§fn with_context(self, otel_cx: Context) -> WithContext<Self>
fn with_context(self, otel_cx: Context) -> WithContext<Self>
Source§fn with_current_context(self) -> WithContext<Self>
fn with_current_context(self) -> WithContext<Self>
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 moreSource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request