mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-09 04:44:01 +00:00
Keep a bikeshare city's last known stations, marked stale, when it comes back into range during a source outage
This commit is contained in:
1 parent
057dbe24af
commit
60a230b2ff
2 files changed
+45
No files matched your search
@@ -375,3 +375,42 @@ test('every status poll failing over cached points reads STALE, not fresh', asyn
|
|||||||
assert.equal(stats.stale, true);
|
assert.equal(stats.stale, true);
|
||||||
assert.equal(stats.lastUpdate, loadedAt, 'a failed poll advanced freshness');
|
assert.equal(stats.lastUpdate, loadedAt, 'a failed poll advanced freshness');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('a city that leaves range and comes back during a status outage keeps its last stations, STALE', async () => {
|
||||||
|
const layer = makeLiveLayer();
|
||||||
|
await layer.moveTo(TORONTO_ONLY);
|
||||||
|
await layer.enable();
|
||||||
|
const loadedAt = layer.stats().lastUpdate;
|
||||||
|
assert.equal(layer.stats().count, 1);
|
||||||
|
|
||||||
|
layer.source.deadStatus.add(TORONTO);
|
||||||
|
await layer.moveTo(BUFFALO_ONLY);
|
||||||
|
const beforeReturn = layer.stats().lastUpdate;
|
||||||
|
await layer.moveTo(TORONTO_ONLY);
|
||||||
|
|
||||||
|
const stats = layer.stats();
|
||||||
|
assert.equal(stats.count, 1, 'the last known stations stay drawn');
|
||||||
|
assert.equal(stats.error, undefined);
|
||||||
|
assert.equal(stats.stale, true, 'they are marked stale');
|
||||||
|
assert.equal(stats.lastUpdate, beforeReturn, 'the outage advanced freshness');
|
||||||
|
assert.ok(layer.state._activeCityIds.has(TORONTO), 'the city stays active');
|
||||||
|
const [station] = layer.state._stationRenderMap.values();
|
||||||
|
assert.equal(station.cityId, TORONTO);
|
||||||
|
assert.equal(station.bikesAvailable, 3, 'the last known status stays');
|
||||||
|
|
||||||
|
// The next poll that reaches the source clears the outage.
|
||||||
|
layer.source.deadStatus.delete(TORONTO);
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 5));
|
||||||
|
await layer.poll();
|
||||||
|
assert.equal(layer.stats().stale, undefined);
|
||||||
|
assert.ok(layer.stats().lastUpdate > loadedAt);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('a city whose status never loaded is still removed when its status fails', async () => {
|
||||||
|
const layer = makeLiveLayer();
|
||||||
|
layer.source.deadStatus.add(TORONTO);
|
||||||
|
await layer.moveTo(TORONTO_ONLY);
|
||||||
|
await layer.enable();
|
||||||
|
assert.equal(layer.stats().count, 0, 'no status ever seen: nothing to keep');
|
||||||
|
assert.equal(layer.stats().error, 'GBFS fetch error');
|
||||||
|
});
|
||||||
@@ -94,6 +94,8 @@ export function createViewport({ state: layerState, services, parts, camera }) {
|
|||||||
async function activateCity(cityId, generation) {
|
async function activateCity(cityId, generation) {
|
||||||
if (!layerState._enabled || !layerState._activeCityIds.has(cityId)) return;
|
if (!layerState._enabled || !layerState._activeCityIds.has(cityId)) return;
|
||||||
|
|
||||||
|
// Set once the city's last known stations and status are back on the map.
|
||||||
|
let showingLastKnown = false;
|
||||||
try {
|
try {
|
||||||
const stationMap = await parts.ingestion.loadCityStationInfo(
|
const stationMap = await parts.ingestion.loadCityStationInfo(
|
||||||
cityId,
|
cityId,
|
||||||
@@ -113,6 +115,7 @@ export function createViewport({ state: layerState, services, parts, camera }) {
|
|||||||
const cachedStatus = layerState._statusCache.get(cityId)?.statusMap;
|
const cachedStatus = layerState._statusCache.get(cityId)?.statusMap;
|
||||||
if (cachedStatus) {
|
if (cachedStatus) {
|
||||||
parts.rendering?.applyStatusToPoints(cityId, cachedStatus);
|
parts.rendering?.applyStatusToPoints(cityId, cachedStatus);
|
||||||
|
showingLastKnown = layerState._cityRuntime.has(cityId);
|
||||||
}
|
}
|
||||||
|
|
||||||
const statusMap = await parts.ingestion.loadCityStationStatus(
|
const statusMap = await parts.ingestion.loadCityStationStatus(
|
||||||
@@ -137,6 +140,9 @@ export function createViewport({ state: layerState, services, parts, camera }) {
|
|||||||
return;
|
return;
|
||||||
console.warn(`[Data:Bikeshare] ${cityId} activate error:`, error);
|
console.warn(`[Data:Bikeshare] ${cityId} activate error:`, error);
|
||||||
layerState._failedCityIds.add(cityId);
|
layerState._failedCityIds.add(cityId);
|
||||||
|
// During a source outage a city coming back into range keeps its last
|
||||||
|
// known stations and status, marked stale; the status poll retries it.
|
||||||
|
if (showingLastKnown) return;
|
||||||
deactivateCity(cityId);
|
deactivateCity(cityId);
|
||||||
layerState._activeCityIds.delete(cityId);
|
layerState._activeCityIds.delete(cityId);
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
Reference in new issue
Block a user