pub struct SessionPixSupervisor {Show 20 fields
pub(crate) cfg: SupervisorConfig,
pub(crate) dims: PixParams,
pub(crate) pseudonym: HoprPseudonym,
pub(crate) closed: bool,
pub(crate) draining: bool,
next_ssa_index: u32,
share_order_front: Option<SsaIndex>,
front_useful: u64,
off_front_useful: u64,
service_open: bool,
service_front: Option<SsaIndex>,
paid_front_handoff: bool,
paid_recovery_tail: Option<PaidRecoveryTail>,
successor_request_deferred: bool,
ssas: Vec<PerSsaState>,
first_failure_reason: Option<SessionPixCloseReason>,
failed_cycles: usize,
fill: FillPlanner,
highest_retired_ssa_index: Option<SsaIndex>,
telemetry: PixTurnEvents,
}Expand description
Deterministic core of the PIX session supervisor.
Fields§
§cfg: SupervisorConfig§dims: PixParams§pseudonym: HoprPseudonym§closed: bool§draining: boolThe Session is gone and only its funded front cycle is still being worked for.
Set by on_session_closed and never cleared: a drain ends by
closing, one way or another. While it is set the supervisor asks for no successor, plans fill
at the ceiling, and stops service-gating the recovery idle deadline — see “Draining a closed
Session” in this module’s documentation for why each of those follows from the Session having
left rather than being separate policy.
next_ssa_index: u32The cycle the two share-order counters below are measured against — the earliest unrecovered
cycle, i.e. the one the Entry should currently be serving. None before the first batch exists.
front_useful: u64Useful shares booked on Self::share_order_front since it took the front.
off_front_useful: u64Useful shares booked on any other live cycle over that same span.
off_front_useful / (front_useful + off_front_useful) is the share-order ratio — see
SupervisorConfig::max_off_front_share_fraction for what it detects and why it is a fraction
rather than a count. Both counters reset when the front changes, which is what keeps the window
bounded to a single cycle’s service.
service_open: boolWhether the service gate currently follows a funded front cycle.
service_front: Option<SsaIndex>Front cycle for which the current gate mode was emitted.
Tracking the identity as well as the mode lets a funded-to-funded handoff rebaseline the served-without-progress ceiling for the newly promoted cycle.
paid_front_handoff: boolA front cycle became paid and terminal in one event, so an unfunded successor still earns a freshly restored predeposit allowance even though the gate never entered funded mode.
paid_recovery_tail: Option<PaidRecoveryTail>The sole recovered predecessor authorized to report buffered liveness.
This never becomes a set: accepting arbitrary recovered tombstones would let the Entry replay old cycle tags to keep service open. Replacement on each in-order recovery is the supervisor’s independent bound behind the reconstructor’s per-polynomial surplus counters.
successor_request_deferred: boolA successor batch was earned but could not yet fit the two-generation reservation.
ssas: Vec<PerSsaState>Ordered SSAs (oldest first, newest last), including short-lived recovered tombstones.
first_failure_reason: Option<SessionPixCloseReason>Tracks the first failure reason when multiple SSAs fail, so the
earliest cause is used for the final Close action rather than the last.
failed_cycles: usizeCycles this Session has lost without recovering them, over its whole life.
Cumulative, and that is the whole point: retiring a failed member leaves no trace on its
siblings, so without a counter that survives the retirement an Entry can lose one cycle per
batch indefinitely while a single funded sibling holds the Session open. Bounded by
SupervisorConfig::max_failed_cycles.
fill: FillPlannerPlans the rate at which this Exit originates its own fill keep-alives.
Kept here rather than in the worker because the rate is a function of the lifecycle state this struct owns — which cycle is at the paid front and how far it has got — and because every close path has to be able to stop it in the same action vector that carries the close.
highest_retired_ssa_index: Option<SsaIndex>Greatest SSA index that has been retired (closed and removed).
Prevents a stale SsaRequestSent from resurrecting a closed SSA. A high-watermark rather
than the set of every retired index: the set grew for the whole life of the Session and was
scanned linearly on every request, one entry per cycle, without bound.
A watermark alone would be wrong if it were consulted first — retirement is not monotone, since a later batch member can lose its deposit while an earlier one is still recovering, and “at or below the greatest retired index” would then condemn that live earlier cycle. The guard is therefore placed after the live-record lookup, so a cycle that still exists always wins and the watermark only ever answers for indices that have none.
telemetry: PixTurnEventsCycle lifecycle transitions since the worker last drained this.
Latched rather than emitted because this type is a pure function of its inputs and a metric
is not — the same arrangement as FillPlanner’s stall, which is latched here and drained
in the worker. Always compiled, including without the telemetry feature, so the default
test configuration exercises the counting rather than only the feature-enabled one.
Implementations§
Source§impl SessionPixSupervisor
impl SessionPixSupervisor
Sourcepub fn new(
cfg: SupervisorConfig,
dims: PixParams,
pseudonym: HoprPseudonym,
now: Instant,
) -> (Self, Vec<SessionPixAction>)
pub fn new( cfg: SupervisorConfig, dims: PixParams, pseudonym: HoprPseudonym, now: Instant, ) -> (Self, Vec<SessionPixAction>)
Create a new supervisor and emit the first RequestSsa action.
Sourcepub fn handle_event(
&mut self,
ev: &SessionPixEvent,
now: Instant,
served_total: u64,
) -> Vec<SessionPixAction>
pub fn handle_event( &mut self, ev: &SessionPixEvent, now: Instant, served_total: u64, ) -> Vec<SessionPixAction>
Handle a lifecycle event.
Sourcefn note_retired_index(&mut self, index: SsaIndex)
fn note_retired_index(&mut self, index: SsaIndex)
Raises the retired-index watermark.
Takes the maximum rather than assuming the caller retires in order, because it does not: a later batch member losing its deposit is retired before an earlier one that is still recovering.
Sourcefn earliest_live_idx(&self) -> Option<usize>
fn earliest_live_idx(&self) -> Option<usize>
Index of the earliest cycle that has not finished recovering — the one the Entry should be serving, given that emission is clamped to a single cycle.
Sourcefn release_paid_tail(&mut self, now: Instant)
fn release_paid_tail(&mut self, now: Instant)
Consumes the predecessor receipt once the current live front has reported any share.
This check is centralized rather than tied only to RecoveryProgress: a previously queued
cycle can become the front because a sibling is retired or because its deposit arrives after
its first snapshot. In every case the observation proves the transport crossed the cycle
boundary. Keeping the old funded receipt beyond it would let an unfunded successor spend the
predecessor’s remaining allowance.
Retires the paid tail, latching how long it held the front.
fn consume_paid_tail_at_observed_boundary(&mut self, now: Instant)
Sourcefn sync_service_gate(&mut self) -> Vec<SessionPixAction>
fn sync_service_gate(&mut self) -> Vec<SessionPixAction>
Keeps the service gate aligned with the funding state of the earliest live cycle.
A funded-to-unfunded handoff restores the configured predeposit allowance. A
funded-to-funded handoff emits ReleaseService too: the mode does not change, but the new
front must receive its own served-without-progress ceiling rather than inheriting the tail of
its predecessor’s. An unfunded cycle that fails does not earn another allowance.
Sourcepub fn telemetry_snapshot(&self, predeposit_exposure: u64) -> PixSessionSnapshot
pub fn telemetry_snapshot(&self, predeposit_exposure: u64) -> PixSessionSnapshot
This Session’s current contribution to the node-level live-set gauges.
Recomputed from ssas and paid_recovery_tail rather than maintained incrementally, which
is what makes the gauges drain on every terminal path without any of those paths having to
know they exist. A Session holds at most ssas_per_request × MAX_OVERLAPPING_BATCHES cycles,
so the scan is over a handful of entries once per turn.
predeposit_exposure comes from the gate, which the caller reads — this type deliberately
knows nothing about the gate’s counters.
Sourcepub fn take_telemetry_events(&mut self) -> PixTurnEvents
pub fn take_telemetry_events(&mut self) -> PixTurnEvents
Drains the cycle lifecycle transitions latched since the last call.
fn live_cycle_count(&self) -> usize
fn live_batch_count(&self) -> usize
fn reserved_cycle_slots(&self) -> usize
fn retry_deferred_successor_request( &mut self, now: Instant, ) -> Vec<SessionPixAction>
Re-points the share-order accounting at the current front of the batch, clearing it if the front moved.
Clearing on a change of front is what bounds the measurement window to one cycle’s service, and it is why an Entry cannot launder a spree by eventually finishing a cycle: the reset is only reached by the front cycle completing, which is the thing the Exit wanted all along.
Called after every event and every deadline sweep, so it covers both ways the front can move — the front cycle recovering, or being retired.
Sourcefn arm_recovery_clocks_for_earliest(&mut self, now: Instant, served_total: u64)
fn arm_recovery_clocks_for_earliest(&mut self, now: Instant, served_total: u64)
Starts the recovery clocks of the earliest unrecovered cycle, if they are not running yet.
A batch’s cycles are served strictly in index order — the Entry’s emission window is clamped to
one cycle (see hopr_protocol_pix::SHARE_EMISSION_WINDOW) — so a cycle behind the front of
the batch is queued, not stalled. Starting its clocks when its deposit confirmed, as this used
to, measured the queue wait rather than the recovery: at deployed dimensions one cycle takes
~61 min of emission to exhaust, so every cycle after the first was retired by
max_recovery_time — or, worse, by max_recovery_idle inside a minute, since the idle gate
compares against session-wide service and a queued cycle sees plenty of that without any of it
being its own.
So the clock starts when the cycle reaches the front, which is when it can actually make
progress, and SupervisorConfig::max_recovery_time then means what its name says: the ceiling
on recovering a single cycle. served_total_at_last_progress is re-baselined at the same moment
for the same reason — otherwise the idle gate would charge the queue wait against it.
Called after every event and every deadline sweep, so it covers each way a cycle can reach the front: its predecessor recovering, or its predecessor being retired.
Sourcepub fn handle_deadline(
&mut self,
now: Instant,
served_total: u64,
) -> Vec<SessionPixAction>
pub fn handle_deadline( &mut self, now: Instant, served_total: u64, ) -> Vec<SessionPixAction>
Check all deadlines and emit actions for any that have expired.
Sourcepub fn handle_timers(
&mut self,
now: Instant,
served_total: u64,
) -> Vec<SessionPixAction>
pub fn handle_timers( &mut self, now: Instant, served_total: u64, ) -> Vec<SessionPixAction>
Runs the deadline sweep and, if one is due, the fill tick — in that order.
The order is the point. The sweep is what arms a promoted cycle’s recovery clocks, consumes a spent FIFO tail and re-aligns the service gate, so running it first means the tick plans against the lifecycle as it is now rather than as it was a second ago. A tick that ran first would spend one whole sampling interval filling for a cycle that had already recovered.
This is the entry point the worker uses; handle_deadline remains
separate because the deadline logic is meaningful — and tested — on its own.
Sourcepub fn handle_fill_tick(
&mut self,
now: Instant,
served_total: u64,
) -> Vec<SessionPixAction>
pub fn handle_fill_tick( &mut self, now: Instant, served_total: u64, ) -> Vec<SessionPixAction>
Re-plans the fill rate, emitting an action only when the rate actually changes.
Sourcepub fn take_fill_stall(&mut self) -> bool
pub fn take_fill_stall(&mut self) -> bool
Reports, once, that fill has fallen back because its target stopped progressing.
Exposed for the worker, which is the layer that may have side effects; this state machine and the planner behind it are pure, so neither can record the metric itself.
Sourcepub fn next_fill_tick(&self) -> Option<Instant>
pub fn next_fill_tick(&self) -> Option<Instant>
When the fill planner next wants to run, or None if there is nothing for it to do.
None while no cycle is being filled for and the stream is already silent, which is what
keeps an unfunded or non-PIX-idle Session from waking its worker once a second for nothing. A
running stream always yields a tick even without a target, because it is owed the zero that
stops it.
Sourcefn fill_target(&self) -> Option<FillTarget>
fn fill_target(&self) -> Option<FillTarget>
The cycle the Exit should currently be filling for, if any.
The recovered predecessor’s FIFO tail wins whenever it exists, for two reasons that point the
same way: its SURBs sit ahead of the successor’s in the Exit’s own buffer, so packets sent now
carry its shares; and it holds the binding hard deadline, since the successor’s clocks are
deliberately not armed until the tail is exhausted (see
arm_recovery_clocks_for_earliest).
Otherwise it is the earliest live cycle, and only once it is both funded and clocked. An unfunded cycle has nothing at stake to be filled for, and a funded one whose clocks have not armed is queued behind a predecessor rather than being served — filling for it would spend SURBs on shares the Entry cannot yet be emitting.
Sourcefn with_fill_stopped(
&mut self,
actions: Vec<SessionPixAction>,
) -> Vec<SessionPixAction>
fn with_fill_stopped( &mut self, actions: Vec<SessionPixAction>, ) -> Vec<SessionPixAction>
Prepends the action that silences the fill stream, when there is one to silence.
Returns actions untouched for a Session that never filled — a disabled one, or one that
closed before its first cycle funded — so the action stream of every non-filling Session is
exactly what it was before this existed.
Sourcepub fn next_deadline(&self) -> Option<Instant>
pub fn next_deadline(&self) -> Option<Instant>
Returns the earliest deadline across all live SSAs, or None.
Sourcepub fn action_result(
&mut self,
action: &SessionPixAction,
ok: bool,
_now: Instant,
) -> Vec<SessionPixAction>
pub fn action_result( &mut self, action: &SessionPixAction, ok: bool, _now: Instant, ) -> Vec<SessionPixAction>
Feed back the result of executing an action.
Sourcefn on_ssa_request_sent(
&mut self,
ssa_id: &SsaId<HoprPseudonym>,
now: Instant,
) -> Vec<SessionPixAction>
fn on_ssa_request_sent( &mut self, ssa_id: &SsaId<HoprPseudonym>, now: Instant, ) -> Vec<SessionPixAction>
Arms the commitment deadline once the request this SSA was registered for has gone out.
The record itself is created by emit_request_next_ssa; this
only starts the clock, because the Entry cannot be late answering a request it has not been
sent yet.
Sourcefn on_commitment_progress(
&mut self,
ssa_id: &SsaId<HoprPseudonym>,
now: Instant,
) -> Vec<SessionPixAction>
fn on_commitment_progress( &mut self, ssa_id: &SsaId<HoprPseudonym>, now: Instant, ) -> Vec<SessionPixAction>
Arms — or re-arms — the re-request timer on a commitment that is under way but not complete.
This is where the issue’s rule lives: a cycle that received nothing never reaches here, so it never asks, which is correct because there is no scope for it to name. And because every arriving part pushes the timer out, the first ask cannot land in the middle of the burst — what the timer measures is a stall in delivery.
Unscaled by the batch size, unlike the two absolute deadlines: this is a per-cycle stall detector, and a batch’s commitment sets do not queue behind one another in a way that would make one cycle’s silence expected.
fn on_commitment_verified( &mut self, ssa_id: &SsaId<HoprPseudonym>, now: Instant, ) -> Vec<SessionPixAction>
Sourcefn on_deposit_confirmed(
&mut self,
ssa_id: &SsaId<HoprPseudonym>,
amount: HoprBalance,
now: Instant,
served_total: u64,
) -> Vec<SessionPixAction>
fn on_deposit_confirmed( &mut self, ssa_id: &SsaId<HoprPseudonym>, amount: HoprBalance, now: Instant, served_total: u64, ) -> Vec<SessionPixAction>
Funds the cycle on the deposit pool’s verdict. The supervisor does not second-guess the amount.
Sufficiency is priced and judged outside this workspace. The Exit’s pool is handed the
DepositUpdated sender together with the byte quota when the
deposit address arrives, and it sends on that channel once the deposit clears the price it
charges for that quota — so by the time this runs, the question has been answered by the only
component that can answer it. Nothing in the Session layer prices a byte.
This used to compare the running total against max(expected_deposit, min_deposit). Both are
gone, and not because they were merely unused: a configured floor here is not a backstop behind
the pool but a second authority alongside it, and one set above the pool’s price fails a cycle
that has already been paid for — silently, on max_deposit_wait, with neither side able to
break the tie. expected_deposit was the same idea arriving over the wire, and the commitment
never carried an amount to fill it.
What remains is the one check that needs no price: a zero balance asserts that nothing was deposited, so it is not a verdict and cannot release service. The deadline keeps running and a later confirmation can still fund the cycle.
fn on_deposit_observer_closed( &mut self, ssa_id: &SsaId<HoprPseudonym>, now: Instant, served_total: u64, ) -> Vec<SessionPixAction>
fn on_recovery_progress( &mut self, progress: &SsaRecoveryProgress<HoprPseudonym>, now: Instant, served_total: u64, ) -> Vec<SessionPixAction>
Sourcefn on_recovered_tail_progress(
&mut self,
progress: &SsaRecoveryProgress<HoprPseudonym>,
now: Instant,
served_total: u64,
) -> Vec<SessionPixAction>
fn on_recovered_tail_progress( &mut self, progress: &SsaRecoveryProgress<HoprPseudonym>, now: Instant, served_total: u64, ) -> Vec<SessionPixAction>
Applies a progress snapshot from the sole recovered predecessor authorized to drain.
The reconstructor enforces the strong per-polynomial budget. These aggregate checks are a
second security boundary: even if that component regresses, the Entry cannot make a recovered
cycle report more than polys × (threshold + surplus) packets, change its terminal useful
count, or revive any older tombstone.
Attributes delta useful shares to the front of the batch or behind it, and judges the ratio.
The Entry serves a batch strictly in index order, so progress on anything but the front cycle is
service the Exit cannot yet be paid for. See
SupervisorConfig::max_off_front_share_fraction for the threat and for why this is measured
as a fraction; the judgement waits for
SupervisorConfig::min_share_order_sample shares of evidence.
fn on_almost_recovered( &mut self, ssa_id: &SsaId<HoprPseudonym>, now: Instant, ) -> Vec<SessionPixAction>
fn on_recovered( &mut self, ssa_id: &SsaId<HoprPseudonym>, now: Instant, served_total: u64, ) -> Vec<SessionPixAction>
Sourcefn book_recovered_cycle(&mut self, idx: usize, now: Instant, served_total: u64)
fn book_recovered_cycle(&mut self, idx: usize, now: Instant, served_total: u64)
Books what a recovered cycle owes the counters and retires it into its tombstone.
Split out because a drain returns before the rest of the transition, and would otherwise
never book the deposit it just unlocked — making the one outcome the drain exists for read as
stranded value in hopr_pix_deposits_recovered_uhopr_total.
Sourcefn perform_recovered_transition(
&mut self,
idx: usize,
now: Instant,
served_total: u64,
) -> Vec<SessionPixAction>
fn perform_recovered_transition( &mut self, idx: usize, now: Instant, served_total: u64, ) -> Vec<SessionPixAction>
Perform the terminal tombstone transition for a fully-recovered SSA.
Called from on_recovered (normal Recovering path) and replayed from
on_deposit_confirmed/on_commitment_verified when recovered_pending
was set earlier.
Closes the Session on the first unverifiable-share report. There is no tolerance to configure.
Shares are not checked on arrival, so a report is not “a bad share” — it means a whole
polynomial’s share set failed to open its commitment, which surfaces only once threshold of
them have been interpolated. SsaPart::add_share then marks that part failed and releases its
shares, and nothing ever clears the flag; since the SSA is the sum of every polynomial’s
constant term, the cycle can no longer be reconstructed by any means and will never pay.
So serving on is not tolerance, it is donation: every packet past this point is unpaid with no
recovery to preserve at the end of it. That holds however the failure arose, which is why this
is not a knob — a false positive from a verification bug leaves the part just as permanently
failed, so a tolerance would buy unpaid service rather than the cycle it was raised to save.
Closing here caps the exposure at the threshold packets already served rather than a multiple
of it.
observed_total is the reconstructor’s cross-peer aggregate, and with no limit to compare it
against it is logged rather than accumulated: it says how many polynomials the batch that
triggered this took down, which is the difference between one bad relayer and a peer sending
garbage wholesale.
Note this closes the Session directly rather than through
close_ssa_and_collect, so a batch’s surviving siblings do not
keep it alive: unlike a lost deposit, this fault is evidence about the peer rather than about
one cycle.
Sourcefn on_session_closed(
&mut self,
available: u64,
_now: Instant,
) -> Vec<SessionPixAction>
fn on_session_closed( &mut self, available: u64, _now: Instant, ) -> Vec<SessionPixAction>
Decides whether a Session closed at the Exit is worth draining its buffered SURBs into.
available is the manager’s estimate of the SURBs still spendable, already net of the fill
reserve. The cycle it is measured against is the earliest live one, and only when it is both
funded and clocked — i.e. exactly the cycle fill would have been working for. Two shapes have
nothing a drain could buy and close at once: an unfunded front, where no deposit is at stake;
and a recovered predecessor’s paid FIFO tail, whose key is already recovered and behind which
the successor is queued without clocks of its own.
The comparison is against the whole remaining emission, with no loss margin. That is
conservative in both directions on purpose: the estimate is an upper bound (see
SessionPixEvent::SessionClosed), while in-flight packets are already subtracted from it
and full recovery in practice needs fewer than E shares. A drain that runs out partway has
spent the Session’s SURBs down to the reserve and recovered nothing, which is strictly worse
than never starting.
Siblings are retired directly rather than through
close_ssa_and_collect, which would be wrong twice over: it
charges failed_cycles, and these cycles were retired by an operator
closing a Session rather than lost by an Entry; and its ssas.len() == 1 branch would close
the Session outright. Recovered tombstones are left alone — they hold no reconstructor state
and expire on their own timer with an idempotent RetireSsa.
_now is taken for symmetry with every other handler; nothing here is timed. A drain inherits
the target’s existing clocks rather than starting any of its own, which is the point — the
resource bound on the cycle must not be extended by the Session ending.
Sourcefn close_ssa_and_collect(
&mut self,
idx: usize,
reason: SessionPixCloseReason,
served_total: u64,
now: Instant,
) -> Vec<SessionPixAction>
fn close_ssa_and_collect( &mut self, idx: usize, reason: SessionPixCloseReason, served_total: u64, now: Instant, ) -> Vec<SessionPixAction>
Close the SSA at idx and return close actions.
Sourcefn emit_request_next_ssa(&mut self, now: Instant) -> Vec<SessionPixAction>
fn emit_request_next_ssa(&mut self, now: Instant) -> Vec<SessionPixAction>
Allocates the next batch of SSA indices and asks for all of them in one action.
The batch size is SupervisorConfig::ssas_per_request, clamped rather than trusted since a
supervisor can be built from a config that never went through validate_pix_supervision.
Exactly one cycle of the batch — the last one allocated — carries
PerSsaState::is_batch_last, and only that cycle may ask for the successor batch. Without
it every member would ask for one of its own, since the request flags are per-cycle; see that
field for why the last rather than the first.
Before allocating, this enforces both halves of the admission reservation: no more than
crate::MAX_OVERLAPPING_BATCHES live generations and no more than that many full batches’
live cycles. A request earned while the reservation is full is retried after a generation
releases its reconstructor state.
What batching does change is the exposure within a batch: every cycle in it is unfunded at
once, so the ceiling is ssas_per_request SSA quotas rather than one. That is the trade the
knob exists to make, and it is why both deadlines are scaled by the same factor.
fn find_ssa_idx(&self, ssa_id: &SsaId<HoprPseudonym>) -> Option<usize>
Auto Trait Implementations§
impl Freeze for SessionPixSupervisor
impl RefUnwindSafe for SessionPixSupervisor
impl Send for SessionPixSupervisor
impl Sync for SessionPixSupervisor
impl Unpin for SessionPixSupervisor
impl UnsafeUnpin for SessionPixSupervisor
impl UnwindSafe for SessionPixSupervisor
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
§impl<T> Conv for T
impl<T> Conv for T
§impl<T> FmtForward for T
impl<T> FmtForward for T
§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.§fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
§impl<T> FutureExt for T
impl<T> FutureExt for T
§fn with_context(self, otel_cx: Context) -> WithContext<Self>
fn with_context(self, otel_cx: Context) -> WithContext<Self>
§fn with_current_context(self) -> WithContext<Self>
fn with_current_context(self) -> WithContext<Self>
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§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§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read more§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read more§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.§impl<T> Pointable for T
impl<T> Pointable for T
§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
§impl<T> Tap for T
impl<T> Tap for T
§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read more§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read more§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read more§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read more§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read more§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read more§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.