pub struct DispatchReservation { /* private fields */ }Expand description
One capacity slot on one worker, held from selection until it is dropped.
Returned by ConnectedWorkerRegistry::select_and_reserve. Dropping it
releases the slot and wakes the selection waits, exactly as a completion
does — so a dispatch that dies anywhere between choosing its worker and
handing the count to the heartbeat tracker gives the slot back without that
path having to know a slot existed. That is the whole point: the release is
owed by the type, not by every error arm.
§Handing the slot over: Self::commit, and why it exists now
This type used to forbid a commit/forget escape, on the reasoning that
the tracker’s own increment would carry the slot afterwards and the two would
merely overlap “for the width of one call”. That was measured and it was
wrong in a way that mattered.
The overlap is two separate acquisitions of the registry lock — the tracker
increments under one, this type’s Drop decrements under another — and
between them the worker’s in_flight reads ONE HIGHER than the number of
dispatches it is actually holding. A concurrent leg that lands in that window
asks ConnectedWorkerRegistry::reserve_worker, is told held >= advertised, and is refused a slot the worker demonstrably has. Observed
directly: in_flight = 5 on a worker advertising 4, on a fan sized exactly
to its pool — which is the normal shape, so the margin is zero and one
collision is enough.
So the handover is now a single act with no intermediate state:
Self::commit disarms this reservation and the tracker skips its own
increment, because the slot this reservation already holds IS the slot the
tracked dispatch holds. The count goes 1 → 1 rather than 1 → 2 → 1, and
never passes through a value that is not true.
The original worry — a missed handoff silently under-counting a busy worker forever — is answered by making the transfer the ONLY way to commit: the tracker takes the reservation by value, so it either commits it or drops it, and a dropped reservation still releases.
Implementations§
Trait Implementations§
Source§impl Debug for DispatchReservation
impl Debug for DispatchReservation
Source§impl Drop for DispatchReservation
impl Drop for DispatchReservation
Auto Trait Implementations§
impl !RefUnwindSafe for DispatchReservation
impl !UnwindSafe for DispatchReservation
impl Freeze for DispatchReservation
impl Send for DispatchReservation
impl Sync for DispatchReservation
impl Unpin for DispatchReservation
impl UnsafeUnpin for DispatchReservation
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> 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> IntoMaybeUndefined<T> for T
impl<T> IntoMaybeUndefined<T> for T
Source§fn into_maybe_undefined(self) -> MaybeUndefined<T>
fn into_maybe_undefined(self) -> MaybeUndefined<T>
Source§impl<T> IntoOption<T> for T
impl<T> IntoOption<T> for T
Source§fn into_option(self) -> Option<T>
fn into_option(self) -> Option<T>
Source§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