Skip to main content

Module driver

Module driver 

Source
Expand description

The #1608 gap-driven fetch driver: [driver::drive] fills only the missing_ranges of a request, paying the minimum, by folding the resume / reseed loop behind the [pacer::Pacer] axis. The #1608 gap-driven, range-minimized fetch driver.

[drive] satisfies a request R = [offset, offset+len) of one blob by filling ONLY the gaps the store is missing, paying the minimum: held ranges are read locally, never pulled, never re-paid. It is the integration keystone of the #1621 ranged-store effort — the piece that turns the sourcing axis ([BlobSource]) and the pacing axis ([Pacer]) into a single fetch that pulls exactly the bytes a request needs.

§The money-relevant branches

A whole-tail pull streams one advancing byte_offset to the end of the blob; drive instead drives the same money-relevant branches per gap: it draws and resumes one missing range at a time. The acquire loop ([crate::acquire]) runs the same per-gap loop on each of its lanes. The branches are:

  • Draw (the happy path): open the gap’s decdn_bao_range::AlignedRange, stream it through [crate::ClientRangedStore::ingest_stream] (which durably checkpoints as it goes), then [BlobSource::finish] to drain the pull and recover the acked voucher watermark. The store’s checkpoints are what make a mid-gap fault re-enter with a SMALLER gap: the store owns durability, so a resume never re-pulls a checkpointed prefix.
  • Refuse: a lane whose deposit cannot cover the next voucher, a node’s Unfunded refusal, and a mid-stream funding rejection all end the lane. The acquire loop marks its source priced out at the current deposit, and adds funds only through the funding recovery step at the exhausted candidate set (ADR 003 § Funding recovery).
  • Paid-frontier resume: within a gap, each new leg opens at the gap’s PAID frontier, NOT its checkpointed (delivered) frontier. [crate::ClientRangedStore::ingest_stream] checkpoints delivered+verified bytes payment-agnostically (the ADR 003 credit window lets the node stream a full interval before the voucher that pays for it is due), so a leg can leave the store’s present-range frontier AHEAD of the last PAID byte. The per-leg resume offset is [sink::content_paid_frontier] of the leg’s paid wire watermark: the tail is re-delivered (ingest_stream re-writes it idempotently) and re-billed. A lane that a funding refusal ends records that tail on its ledger, and the lane’s next drive bills it first.
  • Reseed (wallet-less resync, #1481): an authenticated [WatermarkBundle] that ADVANCES our committed watermark is a healable desync — the driver reseeds the ledger (PoolLedger::reseed) and retries. This is driver-owned, NOT a [PaceDecision] — the reseed check runs ahead of pacing, the same ordering the node’s own miss-pull policy uses.

§What drive does not do

  • No stale-foreign-partial restart-from-zero. A [crate::ClientRangedStore] is keyed to (root, total_bytes) and only ever holds bao-verified ranges, so an ambiguous NotFound can never mean “this file belongs to another blob”: there is no foreign-partial ambiguity to resolve, and resume is always driven by the verified present set.
  • No progress reporting, deadlines, or durable watermark persistence to a BuyerChannelStore — these are the caller’s job. The acked watermark lives in the PoolLedger the caller owns; persisting it across process restarts, and drawing a progress bar, are CLI concerns.

§Store abstraction

The store is generic over [crate::source::IngestStore] (RangedStore + ingest_stream), not the concrete &ClientRangedStore — [crate::ClientRangedStore] is one implementer (the CLI/client backend, writing .partial/.ranges); a node backend admits to the cache and tees to its downstream client through the same seam.

Structs§

PoolExhausted
The shared pool cannot fund the next voucher: its remaining deposit is below the next voucher’s cost (the pacer returned [PaceDecision::Refuse]).