docs: spec for coalescing tile fetches through deck.gl getTileData#556
Draft
kylebarron wants to merge 6 commits into
Draft
docs: spec for coalescing tile fetches through deck.gl getTileData#556kylebarron wants to merge 6 commits into
kylebarron wants to merge 6 commits into
Conversation
Design for #273: a TileBatcher in deck.gl-raster that coalesces deck.gl's per-tile getTileData calls into one getMultiTileData (-> geotiff.fetchTiles) call per zoom level, plus a chunkd request-scheduler middleware in geotiff so maxRequests bounds actual concurrent HTTP requests. No public fetchTiles API change; no loaders.gl dependency in geotiff. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
A minimal slot-acquisition contract — `acquire(signal?): Promise<() => void>` where an abort while queued drops the request without firing it — plus: - `limitFetch(fetch, limiter)`: wraps a Source.fetch to hold a slot for its duration, forwarding the call's signal to acquire(). - `Semaphore`: a FIFO concrete impl. - `defaultLimiterForOrigin(url)`: returns a per-origin shared Semaphore (`maxRequests = 6`) cached across calls, so multiple sources targeting the same host (multiple GeoTIFF.fromUrl, plus future Zarr etc.) share one cap — the relevant constraint is the browser's HTTP/1.1 per-origin connection limit, which is global to the page, not per-layer. No loaders.gl / @chunkd dependency; geotiff stays self-contained. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
When supplied, the data source's fetch is wrapped via limitFetch so every tile-data and mask HTTP request is gated by the limiter. Header/metadata reads are not gated — small, mostly at open time, served from the header cache. GeoTIFF.fromUrl defaults the limiter to defaultLimiterForOrigin(url) — so two `fromUrl` calls (or any other source-level caller) targeting the same origin automatically share one cap. Pass an explicit limiter to override; pass `null` to disable gating. fetchTile / fetchTiles / coalesceRanges are untouched. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The cap that matters is the browser's HTTP/1.1 concurrent-connections- per-origin limit (~6 on Chrome), which is *global to the page* — not per-layer. The earlier design had RasterTileLayer create a layer-scoped RequestScheduler, which can't enforce that cap across multiple layers sharing an origin (two COGLayers on one S3 bucket would each get 6 slots → 12 in flight → browser queues, and stale-after-pan requests block fresh ones). Pivot: - Decouple concurrency limiting from multi-tile coalescing. They were always two concerns; the spec now treats them as independent pieces that can ship and be reasoned about separately. - Move the limiter to the source layer (geotiff). GeoTIFF.fromUrl defaults its concurrencyLimiter to defaultLimiterForOrigin(url), a shared per-origin Semaphore (max=6). Two `fromUrl` calls (or any other source-level caller, future Zarr included) targeting the same origin automatically share one cap, zero setup. - Drop the chunkd SourceMiddleware framing; gate just the data source's .fetch via limitFetch. No SourceView, no chunkd-vs-cogeotiff Source- type cast. - Drop the loaders.gl RequestScheduler adapter from deck.gl-raster. The layer no longer owns or threads a limiter. - Add `signal` to ConcurrencyLimiter.acquire so queued aborts drop rather than fire stale requests after a pan. The TileBatcher work (the deck.gl-raster half) is unchanged in spirit but no longer creates a limiter; it just runs the batcher and sets the inner TileLayer's maxRequests: 0. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
0477ae3 to
6e6b133
Compare
Like fetchTiles, but a single missing tile or a single tile's decode
failure becomes a { error } entry in its slot rather than throwing. A
network-level failure inside a coalesced range still rejects the whole
call (those bytes are gone for every tile in the merged range). Composes
the existing coalesced byte-fetch + per-tile assembleTile pieces; adds a
collect-not-throw variant of fetchCogBytesMultiple. New method on
GeoTIFF + Overview. SettledTile type re-exported from the package.
For the deck.gl batched-fetch path so one bad tile can't blank a viewport.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Buffers per-item fetch() calls and dispatches one batched call per group key on a setTimeout(_, 0); per-item Error distribution; composite "abort-when-all" signal; finalize() rejects what's buffered. Pure coalescer — no limiter ownership, no scheduler — that's the source layer's concern. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Design for #273: a TileBatcher in deck.gl-raster that coalesces deck.gl's per-tile getTileData calls into one getMultiTileData (-> geotiff.fetchTiles) call per zoom level, plus a chunkd request-scheduler middleware in geotiff so maxRequests bounds actual concurrent HTTP requests. No public fetchTiles API change; no loaders.gl dependency in geotiff.