mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 02:44:02 +00:00
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]>
This commit is contained in:
1 parent
4e99f40488
commit
db49edf363
8 files changed
+254
-32
No files matched your search
@@ -60,6 +60,28 @@ export function validTerrainResult(result) {
|
||||
return Boolean(result) && Number.isFinite(result.ellipsoid);
|
||||
}
|
||||
|
||||
/**
|
||||
* A row the upstream DID return for its position, but with no usable height:
|
||||
* Re:Earth sporadically answers with a real `elevation` and a null
|
||||
* `geoid`/`ellipsoid`. Measured at ~0.16% of points, and transient — the same
|
||||
* coordinate resolves on a later poll. That is an absent datum, not a failed
|
||||
* refresh, so the point is left uncached to be re-asked while the client
|
||||
* covers it through its bundled geoid. A null/undefined entry is NOT this
|
||||
* case: it means the position was dropped from the response, which is a
|
||||
* genuine upstream fault.
|
||||
* @param {unknown} result
|
||||
*/
|
||||
export function absentTerrainDatum(result) {
|
||||
return (
|
||||
typeof result === 'object' &&
|
||||
result !== null &&
|
||||
!Array.isArray(result) &&
|
||||
result.ellipsoid === null &&
|
||||
result.geoid === null &&
|
||||
Number.isFinite(result.elevation)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert Retry-After (delta-seconds or HTTP-date) to milliseconds.
|
||||
* @param {string|null|undefined} value
|
||||
@@ -194,24 +216,33 @@ export async function resolveTerrainHeightRequest({
|
||||
|
||||
let cacheChanged = false;
|
||||
let upstreamError = null;
|
||||
let absentPoints = 0;
|
||||
if (missing.length > 0) {
|
||||
try {
|
||||
const fetched = await fetchMissing(missing.map((item) => item.point));
|
||||
if (!Array.isArray(fetched))
|
||||
throw new Error('malformed upstream response (no results array)');
|
||||
const fetchedAt = now();
|
||||
let omittedPositions = 0;
|
||||
for (let i = 0; i < missing.length; i += 1) {
|
||||
const result = fetched[i];
|
||||
if (!validTerrainResult(result)) continue;
|
||||
cache.set(missing[i].key, { at: fetchedAt, result });
|
||||
cacheChanged = true;
|
||||
if (validTerrainResult(result)) {
|
||||
cache.set(missing[i].key, { at: fetchedAt, result });
|
||||
cacheChanged = true;
|
||||
} else if (absentTerrainDatum(result)) {
|
||||
// Upstream answered but had no height. Transient, so deliberately
|
||||
// left uncached: the next poll re-asks and usually succeeds.
|
||||
absentPoints += 1;
|
||||
} else {
|
||||
// Missing or malformed positions remain upstream faults.
|
||||
omittedPositions += 1;
|
||||
}
|
||||
}
|
||||
if (
|
||||
fetched.length !== missing.length ||
|
||||
missing.some((_, i) => !validTerrainResult(fetched[i]))
|
||||
) {
|
||||
if (omittedPositions > 0 || fetched.length !== missing.length) {
|
||||
const dropped =
|
||||
omittedPositions || Math.abs(fetched.length - missing.length);
|
||||
upstreamError = new Error(
|
||||
'upstream omitted one or more terrain heights',
|
||||
`upstream omitted ${dropped} terrain position(s)`,
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
@@ -232,6 +263,8 @@ export async function resolveTerrainHeightRequest({
|
||||
},
|
||||
cacheChanged,
|
||||
upstreamError,
|
||||
absentPoints,
|
||||
requestedPoints: unique.size,
|
||||
};
|
||||
}
|
||||
return {
|
||||
@@ -239,5 +272,7 @@ export async function resolveTerrainHeightRequest({
|
||||
body: { results },
|
||||
cacheChanged,
|
||||
upstreamError,
|
||||
absentPoints,
|
||||
requestedPoints: unique.size,
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user