pub struct ErrorGraph { /* private fields */ }Expand description
Every failure the device is still holding, and how many allocations carry each one.
Implementations§
Source§impl ErrorGraph
impl ErrorGraph
Sourcepub const MAX_SKIPPED: usize = 16
pub const MAX_SKIPPED: usize = 16
How many Skipped records one failure keeps. Newest win: the walk a
read makes starts from the most recent buffers, so keeping the oldest
would leave them with no entry to start from, while a deep chain
reaching a gap before the root costs nothing — the root is on the node
itself and never in the list.
Sourcepub fn insert(&mut self, error: ServerError) -> FailureId
pub fn insert(&mut self, error: ServerError) -> FailureId
Hold error until nothing carries its id any more.
The node starts carried by nothing, so a caller that taints no slice
with it must hand it back through prune — otherwise
the node waits forever for a decrement that is never coming.
Sourcepub fn skipped(&mut self, failure: FailureId, record: Skipped)
pub fn skipped(&mut self, failure: FailureId, record: Skipped)
Record a launch failure stopped — see Skipped. Keeps the newest
MAX_SKIPPED records and counts them all.
Sourcepub fn report(
&self,
failure: FailureId,
memory: ManagedMemoryId,
) -> Option<ServerError>
pub fn report( &self, failure: FailureId, memory: ManagedMemoryId, ) -> Option<ServerError>
The report a read of memory gets when failure claims its bytes:
the root error, and the path from this buffer back toward it,
reconstructed by walking the skip records backwards.
Sourcepub fn reports(
&self,
claims: impl Iterator<Item = Claim>,
) -> Result<(), ServerError>
pub fn reports( &self, claims: impl Iterator<Item = Claim>, ) -> Result<(), ServerError>
The report a read owes for the claims it found: one error per distinct failure, however many of the buffers carry it, and one per buffer that was never allocated. The second kind is not in the graph, since nothing could carry it, but it is the same answer to the same question.
This is the shape of every “were these bytes written” answer in the
system — FailureStore::ensure_written
and any harness standing in for it — so the dedup and the wrapping live
here rather than once per caller.
§Errors
ServerError::Several naming each failure once, in the order the
claims were found. The caller has nothing to retry — the bytes are gone
— so this is the answer to the read, not a hint to try again.
Sourcepub fn untag(&mut self, failure: Option<FailureId>)
pub fn untag(&mut self, failure: Option<FailureId>)
One fewer allocation carries failure; the node is dropped when none
does.
This is what every shedding path calls — a slice written again, rebound to a new allocation, coalesced away, tombstoned or swept — and the decrement is immediate rather than collected into a list drained later, so a node nothing can reach is never retained just because nothing got around to saying so.
Sourcepub fn replace(&mut self, failure: FailureId, error: ServerError)
pub fn replace(&mut self, failure: FailureId, error: ServerError)
Swap the error behind failure for error, leaving every carrier
pointing at the new one.
This is the exit half of a write scope: entry taints the write set with a provisional node, because the real failure does not exist yet, and exit lands the real one here. A missing node is left missing — the id outlived its carriers, so nothing can read the error either way.
Sourcepub fn prune(&mut self, failure: FailureId)
pub fn prune(&mut self, failure: FailureId)
Drop failure if nothing took its id — for a failure that turned out
to taint nothing, whose node would otherwise wait forever at zero.
Sourcepub fn error(&self, failure: FailureId) -> Option<&ServerError>
pub fn error(&self, failure: FailureId) -> Option<&ServerError>
The error behind failure.
None means the id outlived its node, which the refcount exists to
prevent; a reader treats it as no failure rather than panicking on the
device thread.
Trait Implementations§
Source§impl Debug for ErrorGraph
impl Debug for ErrorGraph
Auto Trait Implementations§
impl !RefUnwindSafe for ErrorGraph
impl !UnwindSafe for ErrorGraph
impl Freeze for ErrorGraph
impl Send for ErrorGraph
impl Sync for ErrorGraph
impl Unpin for ErrorGraph
impl UnsafeUnpin for ErrorGraph
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> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
impl<T> ErasedDestructor for Twhere
T: 'static,
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