pub enum PullMiss {
Clean,
LocalFault,
BelowMargin,
FundingNeeded,
Unfunded,
}Expand description
Why an attempt — one candidate, or a whole walk of them — produced no payload (#1560).
The only distinction the callers need is whether the failure was OURS, because
that is what decides the answer this node signs to its own client. Collapsing
every non-hit onto a clean NotFound — no providers, all refused, all stalled,
and a LOCAL fault alike — makes a false statement about the content in the last
case: the blob may well exist and be perfectly reachable; it is
this node that cannot sign a voucher for it. A broken node answers Declined
rather than launder its own defect into a signed claim about content.
Deliberately NOT a per-verdict taxonomy. The crate-private PullVerdict
already carries the full one, and it answers a different question (“what does
this failure say about the PEER?”); this answers “what may we tell the
client?”. Only its OurLocalFault arm changes that answer: a wedged lane to
ONE provider is not node-wide degradation, and it already has its
own remedy (keep the row, suppress the provider).
#[must_use]: a classifier’s verdict dropped rather than propagated silently
reintroduces the #1560 mis-attribution at that call site — this node’s own
fault signed to a client as an absent blob. Dropping a PullVerdict is
legitimate at the two
mid-stream sites (the answer is already on the wire) and they say so with let _ =,
which satisfies this attribute; dropping a PullMiss never is.
Variants§
Clean
Nothing about the failure blames this node — the honest empty answer, and
the one a wire NotFound is true of.
LocalFault
The attempt failed on a fault in THIS node: a broken signer, a bad encode/range, an unusable deadline config, an upstream that could not VERIFY a signature we produced, or a cache store that could not take the bytes. Says nothing about whether the content exists.
BelowMargin
Candidates existed but every one quoted above the serve-economics buy
ceiling; the node declined an unprofitable relay. Wire-identical to
Self::Clean.
FundingNeeded
This node’s own wallet cannot fund a buyer pool, so it can pay no
provider and the fill ends “funding needed”. The funding problem is this
node’s, not the requester’s, so it is wire-identical to Self::Clean
(ADR 005 §Open-time refusal classes).
Unfunded
The candidate refused this node’s funding: an Unfunded refusal, a
funding voucher rejection, or this node’s pool short of the next
voucher. The refusal scopes to that candidate; a walk that delivers
nothing runs its funding recovery step for such candidates (ADR 003
§ Funding recovery). Wire-identical to Self::Clean.
Implementations§
Trait Implementations§
impl Copy for PullMiss
impl Eq for PullMiss
impl StructuralPartialEq for PullMiss
Auto Trait Implementations§
impl Freeze for PullMiss
impl RefUnwindSafe for PullMiss
impl Send for PullMiss
impl Sync for PullMiss
impl Unpin for PullMiss
impl UnsafeUnpin for PullMiss
impl UnwindSafe for PullMiss
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<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
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