Merge branch 'main' into contrib/gods-003-boundary-probe-recovery-20261011-reviewed

This commit is contained in:
Said Turksever authored and GitHub committed 2026-10-15 14:47:47 +01:00
commit e3d6609f08
99 files changed
+12206 -157

No files matched your search

+10 -12
View File
@@ -272,28 +272,26 @@ export function createTerrainHeights({
const uncached = [];
const seenKeys = new Set();
const now = Date.now();
// What this call resolved or found warm, so the assembly below can report a
// point even if a later chunk's writes pushed it past CACHE_MAX_ENTRIES.
// Without it a batch big enough to evict its own entries would report
// points as unresolved that it had in fact resolved.
const resolvedThisCall = new Map();
for (const item of work) {
const entry = cache.get(item.key);
const entry = cacheTouch(item.key);
const fallbackCooling =
entry?.source === 'geoid-fallback' &&
Number.isFinite(entry.retryAt) &&
now < entry.retryAt;
if (
(entry && entry.source === 'reearth') ||
fallbackCooling ||
seenKeys.has(item.key)
)
if ((entry && entry.source === 'reearth') || fallbackCooling) {
resolvedThisCall.set(item.key, entry);
continue;
}
if (seenKeys.has(item.key)) continue;
seenKeys.add(item.key);
uncached.push(item);
}
// What this call resolved, so the assembly below can report a point even
// if a later chunk's writes pushed it past CACHE_MAX_ENTRIES. Without it a
// batch big enough to evict its own earlier chunks would report points as
// unresolved that it had in fact just resolved.
const resolvedThisCall = new Map();
// Resolve the network path in sequential <=CHUNK_SIZE chunks. Each chunk's
// failure is isolated to that chunk's points (geoid fallback), so a single
// bad chunk doesn't lose results for the rest of a large batch.
+41
View File
@@ -114,6 +114,47 @@ test('a batch larger than the cache bound still reports every point it resolved'
assert.equal(warm.length, 4);
});
test('warm batch consumers retain their terrain cells ahead of unused cells', async () => {
let calls = 0;
const terrain = createTerrainHeights({
maxCacheEntries: 2,
source: {
async getHeights(points) {
calls++;
return points.map((p) => ({ ellipsoid: 100 + p.lon }));
},
},
});
const p = (lon) => ({ lat: 0, lon });
await terrain.resolveEllipsoidalGround([p(1)]);
await terrain.resolveEllipsoidalGround([p(2)]);
await terrain.resolveEllipsoidalGround([p(1)]);
assert.equal(calls, 2);
await terrain.resolveEllipsoidalGround([p(3)]);
assert.equal(terrain.cachedEllipsoidalGround(0, 1), 101);
assert.equal(terrain.cachedEllipsoidalGround(0, 2), null);
assert.equal(calls, 3);
});
test('a batch still reports its warm points after its own fetches evict them', async () => {
const terrain = createTerrainHeights({
source: stubSource(),
maxCacheEntries: 2,
});
await terrain.resolveEllipsoidalGround([pointAt(0)]);
const results = await terrain.resolveEllipsoidalGround([
pointAt(0),
pointAt(1),
pointAt(2),
]);
results.forEach((result, i) => {
assert.equal(result.source, 'reearth', `point ${i} reported resolved`);
assert.equal(result.ellipsoid, heightAt(lonAt(i)));
});
});
test('an out-of-range cache bound falls back to the default instead of disabling the cache', async () => {
for (const maxCacheEntries of [0, -1, Number.NaN, undefined]) {
const terrain = createTerrainHeights({