Skip to main content

Module retry

Module retry 

Source
Expand description

The one retry policy: bounded attempts, one backoff, one classification of transient versus permanent. Retry is the second choice; see the module docs for what must never be routed through it. The one retry policy: bounded attempts, one backoff, one classification.

§Why this module is small on purpose

Retry is the SECOND choice, never the first. A failure that can be prevented by design must be prevented, because a retry that fires is evidence of a defect rather than a success. The trap this module is shaped to avoid is “it will just retry” becoming a reason to ship a racy read, an unbounded allocation, or a path that fails under ordinary conditions.

Three deliberate properties enforce that:

  1. No catch-all cause. [classify_io] returns None for anything it does not recognise, and None means permanent: the error is returned unchanged and the operation is not attempted again. Making a new failure recoverable therefore requires naming it, in public, in keyhog_profile::RetryCause. There is no bucket to quietly widen.
  2. Every attempt is counted. [retry_classified] records one keyhog_profile::record_retry per retry attempt, whether or not the retry eventually succeeded. A path that silently retries a thousand times reports a thousand, so it shows up as a defect rather than as comfort.
  3. One bound, one backoff. [RetryPolicy::DEFAULT] is the only policy. Callers do not get to pick a bigger number because their path is flakier; a path that needs more attempts needs a fix instead.

§What must never be routed through here

Cap refusals. The docker tar entry-count cap, the docker unpack budget, the PDF string-parser work budget, --max-file-size, and the seventeen configured source limits are deliberate refusals of input that is too big, too many, or hostile. Retrying a hostile input turns a denial-of-service defence into a denial of service. They stay one-shot refusals and are reported as coverage gaps, never as transient failures.

Equally: a permission denial, a genuinely absent operator-supplied path, and a malformed URL are permanent. They fail identically on every attempt, so a retry only burns the bound and delays the report.

Structs§

OpenedFile
A file and the metadata of the exact inode that was opened.
RetryPolicy
Bounded attempts with exponential backoff.
RetryingContentSource
Wraps a FileContentSource so its transient arm is retried under the shared policy and its permanent arm is not.

Enums§

PathOrigin
Who named the path, which decides whether “not found” is a race or a fact.

Functions§

classify_io
Classify an IO error, or return None when it is permanent.
open_enumerated
Open an already-enumerated path once and take its metadata from the HANDLE.
retry_classified
Run op under the shared policy, retrying only what classify names.
retry_io
retry_classified specialised to io::Error and classify_io.