Expand description
An HTTP(S)-backed RangeReader for native hosts (SPEC.md §9): point it at
a URL and it fetches only the byte ranges a query needs via HTTP Range
requests. Behind the http feature, because it brings a network stack; the
CLI, the Python wheels and the R package all read remote files through this
one implementation. The browser engine has its own readers (sync XHR and
fetch), which follow the same contract.
Uses blocking ureq with rustls (the tls feature), so http:// and
https:// both work — the file can live on S3, GitHub, or any CDN that honors
Range, which is the format’s whole deployment story.
Remote time is round trips, not bytes, so the reader does three things:
- One agent, kept-alive connections. Every request goes through one
ureq::Agentwhose pool keeps up toFetchPolicy::concurrencyidle connections to the host.ureq::getbuilds a fresh agent per call, so each range used to open (and, onhttps://, TLS-handshake) its own connection: one to three extra round trips per request. - Batches in parallel.
RangeReader::read_many(the engine’s batch of tile or dictionary-chunk faults for one query step) goes out with up toFetchPolicy::concurrencyrequests in flight, from a work queue, so one slow range does not hold up the ranges queued behind it. - Nearby ranges coalesced. Ranges of one batch at most
FetchPolicy::coalesce_gapapart are fetched as one request (up toFetchPolicy::max_spanlong) and sliced apart again.
A transient failure (a dropped connection, a short body, 408/429/5xx)
is retried with exponential backoff; a permanent one (a 404, a
Content-Range for the wrong offset) fails at once. Any range of a batch
failing fails the batch, and the ranges still queued are not started.
A host that ignores Range answers 200 with the whole body (a plain
static server, a proxy that strips the header, a CDN serving a cached full
object). That body has crossed the network by the time the reader sees it,
and every later range request would download it again, so when it is the
file — exactly the length the open measured — and at most
FetchPolicy::whole_body_cap (WHOLE_BODY_CAP, 256 MiB, the browser
readers’ cap) it is kept, and every read from then on is a slice of it. A
larger body is refused by name, without being read: the reader never holds
more than the cap of a body nobody asked for. Taking the first len bytes
of a 200 as if they were the range is the one thing it never does.
Structs§
- Fetch
Policy - How
HttpRangeReaderfetches: fan-out, coalescing, retries, and the whole-body cap.FetchPolicy::from_envreads it once when a reader opens. - Http
Range Reader - An HTTP(S)
RangeReader: kept-alive connections, parallel and coalesced batches, retries, and the bounded whole-body fallback for hosts that ignoreRange(see the module docs).
Constants§
- WHOLE_
BODY_ CAP - The largest whole body (a
200to a range request) the reader keeps and serves reads from — the same 256 MiB the browser readers keep.