Commit Graph
12 Commits
Author SHA1 Message Date
Said Turksever c1820aea49 fix(terrain): end retries early on a long Retry-After; cover the 429 pause
A Retry-After longer than the 10 s retry budget used to sleep the whole
budget out and then give up, so the proxy's 429 pause started 10 s late
and every new-point poll in that window still went upstream and logged.
The retry loop now stops at once in that case.

Tests: the retry loop no longer sleeps for an unreachable Retry-After;
fully cached points, including stale ones, are served during the pause
with no upstream call; a 503 does not pause; a shorter concurrent
Retry-After never cuts the pause short. CURRENT-STATE now says which
requests are still served and which log.
2026-10-28 14:09:12 +00:00
quanticsoul4772andClaude Opus 5.5 923211c24a fix(terrain): key the 429 pause on status, never shorten it, and document it
Review follow-ups: the upstream error now carries its HTTP status and the
pause checks error.status instead of the message text; concurrent 429s
extend the pause with Math.max rather than a shorter Retry-After cutting a
longer one short; the per-chunk re-check says it is for multi-chunk
requests; the first 429 test runs its backoff on mocked timers.
CURRENT-STATE describes the pause.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-25 17:08:26 -07:00
quanticsoul4772andClaude Opus 5.5 d7986309b6 fix(terrain): pause upstream calls after a 429
A rate-limited upstream got asked again by every page request for new
points (about once a second while the camera moves), each with its own
retries, which kept the limit in force and logged "refresh incomplete" each
time. After a 429 the proxy now leaves the upstream alone for its
Retry-After (at most 10 minutes), or 60 s when it sends none, serving
cached points meanwhile. The warning that starts the pause says
"(HTTP 429; pausing upstream for N s)"; requests refused during the pause
don't log.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-25 16:31:08 -07:00
daikaginza e60cbb42e3 perf(terrain): evict from the front of the point cache instead of sorting it
Once the cache was full, every write sorted all 50,000 entries to find the
oldest. A Map keeps insertion order, so keep the map in fetch-time order
and delete from the front: the resolver re-inserts each point it refetches
(an overwrite would leave it in its old place), and the disk load sorts
once, since a file written before this change, or a migrated raw-batch
cache, is not in age order.

Suggested by asturksever on #975.
2026-10-23 11:57:37 +07:00
Said 7860cbf59e fix(terrain): bound each height request to one upstream chunk 2026-10-20 00:57:24 +01:00
Sunilanddaikaginza c7ff33ac2e fix(server): admit reverse-proxied same-origin terrain requests
Review follow-up on #975. The shared same-site gate refuses any forwarding header, which is right for routes that spend a key, but terrain is keyless and needed for rendering: behind the reverse proxy the README documents, every /api/terrain/heights chunk got 403 and fell back to the geoid. Terrain now uses admitSameSiteKeyless, which keeps the Sec-Fetch-Site and exact-Origin checks (comparing Origin against a single X-Forwarded-Proto scheme) but does not refuse forwarding headers. The shared admitSameSite gate is unchanged for every other route. The changelog entry moves to changelog.d/975-terrain-cross-site-gate.md.

Co-authored-by: daikaginza <[email protected]>
2026-10-17 14:36:24 +05:30
Sunilanddaikaginza ff799d1520 fix(server): refuse cross-site requests on the terrain-heights route
Follow-up to #686 requested on #923. The route's per-client limiter keys on the socket address, which for a cross-site <img> is the visitor's own browser, so any web page could fill the bounded cache with junk keys and spend the visitor's 90/min quota, leaving the app's own terrain lookups on 429. Gate the route with admitSameSite before the limiter, like the Places routes.

Co-authored-by: daikaginza <[email protected]>
2026-10-08 21:13:16 +05:30
daikaginza be7187cea7 fix(server): bound the terrain-heights cache and its request rate
Every distinct 5-decimal point was a permanent in-memory entry, a
permanent line in an uncapped `.gev-cache/terrain-heights.json`, and a
live upstream call. Nothing limited the rate, and coordinates were
checked for being finite rather than for being on Earth, so an
out-of-range pair was still a valid cache key.

Four bounds, each following a pattern this repo already uses:

- WGS-84 range is enforced in `parseTerrainPoints`, at the edge, so no
  later stage has to. Poles and the antimeridian still parse.
- The point cache holds at most 50,000 entries and evicts oldest-first,
  the shape `trackBackfillProxies` uses. Sized from measurement: this
  checkout's cache file held 6,189 entries in 1.0 MB of real use, so the
  ceiling is eight times that working set. Terrain does not move, so an
  evicted point costs one refetch and never a wrong answer.
- A cache file above 24 MB is not read back, mirroring
  `rocketLaunchesProxy`. An unmeasurable file is not treated as an
  oversized one: without stat, readFile decides, exactly as before.
- The route carries an always-on limiter of 90/min per client, 270
  global — the `/api/overpass` band, and an order of magnitude above
  measured demand (a full test:track run drove 10 requests, peak 8/min).

The ceilings are constructor options so they can be exercised as
behaviour rather than asserted as constants; production passes none.
They are destructured in the body because `proxyErrorResponses.test.mjs`
slices these proxies to the first column-zero closing brace.
2026-09-27 22:10:43 +07:00
DESTAQandSameh Khamis db49edf363 fix(terrain): keep cold height requests within the browser deadline (#348)
Use 64-point browser and upstream terrain batches to reduce cold-cache timeouts. Preserve successful chunk results, distinguish absent readings from malformed responses, and reject fabricated zero heights.

Original terrain resilience contribution by ItzDESTAQ, with browser batching, validation and regression follow-up by Sameh Khamis.

Validated with unit/build/format/boundary checks, 108 tracking checks, 5 terrain-outage checks, controlled slow-upstream comparison and live browser checks.

Co-authored-by: ItzDESTAQ <[email protected]>
Co-authored-by: Sameh Khamis <[email protected]>
2026-09-12 14:04:08 -07:00
Jejugo a0f07b752f fix: register data providers for local preview
Adapt the preview middleware contribution from PR #324 to the extracted provider modules, including the existing OpenSky route.
2026-09-12 12:43:54 -07:00
Sameh Khamis a2d6461b52 style: format terrain traffic fire and bike-share modules 2026-09-11 21:57:51 -07:00
Sameh Khamis f4054469d5 refactor: split terrain traffic fire and bike-share providers 2026-09-11 21:57:50 -07:00