mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 19:04:02 +00:00
fix(perimeters): report a stale WFIGS snapshot as stale, and stop serving it after a day
When WFIGS was unreachable the proxy served its last snapshot, marked stale
(X-Data-Stale, body.stale), with no age limit, and the client source kept
only the rows. The layer then read healthy with a fresh update time and
get_fire_perimeters reported the perimeters as current; three days into an
outage it still said "1 mapped wildfire perimeter in the requested box."
The source now offers getSnapshotDetail ({rows, stale, fetchedAt}); the
layer reports stale with the snapshot's fetch time, the tool adds stale,
retrieved_at and "(data may be stale)", and the proxy serves a stale
snapshot for at most 24 hours, as the GNSS proxy caps its own.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
2006c035d9
commit
25973ade2c
8 files changed
+190
-9
No files matched your search
@@ -257,7 +257,14 @@ export const getFirePerimeters = defineTool({
|
||||
requires: ['perimeters'],
|
||||
async run(args, { services, signal }) {
|
||||
const area = await resolveArea(args.area, { services, signal });
|
||||
const rows = (await services.perimeters.getSnapshot({ signal }))
|
||||
const snapshot =
|
||||
typeof services.perimeters.getSnapshotDetail === 'function'
|
||||
? await services.perimeters.getSnapshotDetail({ signal })
|
||||
: { rows: await services.perimeters.getSnapshot({ signal }) };
|
||||
// The proxy answers from its last snapshot, marked stale, while WFIGS is
|
||||
// unreachable.
|
||||
const stale = snapshot.stale === true;
|
||||
const rows = snapshot.rows
|
||||
.filter((fire) => polygonsTouchArea(fire.polygons, area))
|
||||
.map((fire) => ({ fire, point: polygonCenter(fire.polygons) }))
|
||||
.filter(({ point }) => point)
|
||||
@@ -279,9 +286,13 @@ export const getFirePerimeters = defineTool({
|
||||
}))
|
||||
.sort((a, b) => (b.acres ?? 0) - (a.acres ?? 0));
|
||||
return {
|
||||
summary: `${countNoun(rows.length, 'mapped wildfire perimeter')} in ${area.label}.`,
|
||||
summary:
|
||||
`${countNoun(rows.length, 'mapped wildfire perimeter')} in ${area.label}` +
|
||||
(stale ? ' (data may be stale).' : '.'),
|
||||
data: {
|
||||
view: suggestView(services, { area, layers: ['fire-perimeters'] }),
|
||||
stale,
|
||||
retrieved_at: isoTime(snapshot.fetchedAt),
|
||||
...capRows(rows, args.limit),
|
||||
},
|
||||
};
|
||||
|
||||
@@ -871,3 +871,39 @@ test('installation names wait for the name pack, briefly', async (t) => {
|
||||
assert.equal(slow.data.names_pending, true);
|
||||
assert.match(slow.summary, /site names are still loading\)\.$/);
|
||||
});
|
||||
|
||||
test('stale fire perimeters say so, with when they were fetched', async () => {
|
||||
const fetchedAt = Date.UTC(2026, 9, 22, 6);
|
||||
const ring = [
|
||||
[
|
||||
[-118.5, 35.2],
|
||||
[-118.4, 35.2],
|
||||
[-118.4, 35.3],
|
||||
[-118.5, 35.2],
|
||||
],
|
||||
];
|
||||
const perimeters = {
|
||||
getSnapshot: async () => [],
|
||||
getSnapshotDetail: async () => ({
|
||||
rows: [
|
||||
{
|
||||
stableId: 'held',
|
||||
name: 'Held Fire',
|
||||
acres: 300,
|
||||
polygons: [ring],
|
||||
},
|
||||
],
|
||||
stale: true,
|
||||
fetchedAt,
|
||||
}),
|
||||
};
|
||||
const result = await catalogWith({ perimeters }).call('get_fire_perimeters', {
|
||||
area: { bbox: [-120, 34, -117, 36] },
|
||||
});
|
||||
assert.equal(
|
||||
result.summary,
|
||||
'1 mapped wildfire perimeter in the requested box (data may be stale).',
|
||||
);
|
||||
assert.equal(result.data.stale, true);
|
||||
assert.equal(result.data.retrieved_at, new Date(fetchedAt).toISOString());
|
||||
});
|
||||
Reference in new issue
Block a user