fix(mapillary): tile flights own their abort, callers only wait on them

fetchTile coalesced concurrent requests for one tile onto a single
upstream fetch, but that fetch ran on the first caller's signal. When the
first request was abandoned (an older pan), every joined request lost a
tile it still needed; and a joined caller that aborted stayed subscribed
until the shared fetch finished.

A flight now owns its AbortController and counts waiters, the pattern the
weather and wind providers use. Each caller's own abort rejects that caller
at once; the upstream fetch is cancelled only when the last waiter leaves,
and a later request after that starts a fresh fetch.

Regression tests (fail on the previous tiles.js, pass now): a joined
request survives the first caller aborting with one upstream request; a
joined caller that aborts leaves at once while the first still gets the
tile; both waiters leaving cancels the owned fetch.

Reported by kvnloo in review.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
Said TurkseverandClaude Opus 5.5 committed 2026-09-28 21:53:40 +01:00
1 parent ecb16b2fe2
commit d7d5bec752
3 files changed
+187 -8

No files matched your search

+4 -1
View File
@@ -2784,7 +2784,10 @@ Share options: `m` (Mapillary on/off), `p` (a/p/f panorama mode), `s`
turns amber and the controls stay disabled; with it, coverage draws as
ground-clamped sequence lines (z0–5 overview points from orbit, z11–14
sequences below 60 km) and the proxy strips the unused `image` point layer
from z14 tiles in transit (12 MB → ~80 KB).
from z14 tiles in transit (12 MB → ~80 KB). Concurrent requests for one tile
share a single upstream fetch that owns its own abort controller: a request
that is abandoned leaves at once without cancelling the others, and the fetch
is cancelled only when its last waiter leaves.
On Google 3D (`photoreal`) at street zoom the layer switches its surface mode
from `draped` to `terrain` (`getUIState().surface`; in below 1,400 m above the