mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-04 02:14:01 +00:00
fix(gnss): expire stale cells on re-enable; pin the unpruned return-after-window path
Re-enabling after a disable longer than the window no longer shows the old cells until the next refresh. A healthy report arriving 31 minutes after a degraded one, with no prune in between, starts clean; exactly 30 minutes still counts.
This commit is contained in:
1 parent
fde8b2a64f
commit
7e570a79ad
4 files changed
+43
-6
No files matched your search
@@ -63,7 +63,6 @@ const getOpt = (name, dflt) => {
|
||||
const APP_URL = getOpt('--url', 'http://localhost:4173');
|
||||
const HEADFUL = argv.includes('--headful');
|
||||
const LAYER_ID = 'gnss-interference';
|
||||
/** Live rows below this cannot reliably fill a 3-aircraft cell. */
|
||||
|
||||
const results = [];
|
||||
function record(name, ok, detail) {
|
||||
|
||||
@@ -122,7 +122,11 @@ export function createGnssIntegrityLayer({
|
||||
|
||||
enable() {
|
||||
_enabled = true;
|
||||
if (_dataSource) _dataSource.show = true;
|
||||
// Cells left from before a long disable must not reappear past the window.
|
||||
if (_dataSource) {
|
||||
expire();
|
||||
_dataSource.show = true;
|
||||
}
|
||||
},
|
||||
|
||||
disable() {
|
||||
|
||||
@@ -284,6 +284,21 @@ test('cells expire while no view anchor is available', async () => {
|
||||
assert.equal(layer.getStats().error, null);
|
||||
});
|
||||
|
||||
test('re-enabling after a long disable does not show cells past the window', async () => {
|
||||
const { layer, sources, advance, now } = harness(async () => ({
|
||||
rows: threeHealthy(),
|
||||
fetchedAt: now(),
|
||||
}));
|
||||
layer.enable();
|
||||
await layer.update();
|
||||
assert.equal(sources[0].entities.values.length, 1);
|
||||
layer.disable();
|
||||
advance(31 * MIN);
|
||||
layer.enable();
|
||||
assert.equal(layer.getStats().count, 0);
|
||||
assert.equal(sources[0].entities.values.length, 0);
|
||||
});
|
||||
|
||||
const threeCells = () => ({
|
||||
rows: [row('a1', 50.1, true), row('a2', 50.1, true), row('a3', 50.2, false)],
|
||||
});
|
||||
|
||||
@@ -305,10 +305,29 @@ test('an aircraft returning after the window starts fresh', () => {
|
||||
degradedAt: null,
|
||||
});
|
||||
// Returning degraded dates the evidence from the new report.
|
||||
accumulateGnssObservations(store, [report('a9', true)], 0);
|
||||
accumulateGnssObservations(store, [], 31 * MIN);
|
||||
accumulateGnssObservations(store, [report('a9', true)], 33 * MIN);
|
||||
assert.equal(entry(store, 'a9').degradedAt, 33 * MIN);
|
||||
const again = new Map();
|
||||
accumulateGnssObservations(again, [report('a9', true)], 0);
|
||||
accumulateGnssObservations(again, [], 31 * MIN);
|
||||
accumulateGnssObservations(again, [report('a9', true)], 33 * MIN);
|
||||
assert.equal(entry(again, 'a9').degradedAt, 33 * MIN);
|
||||
});
|
||||
|
||||
test('an aircraft heard healthy right after the window drops its stale degraded evidence', () => {
|
||||
// No prune runs in between: the old entry is still in the store when the
|
||||
// healthy report arrives, so the new report alone must not carry it over.
|
||||
const store = new Map();
|
||||
accumulateGnssObservations(store, [report('a1', true)], 0);
|
||||
accumulateGnssObservations(store, [report('a1', false)], 31 * MIN);
|
||||
assert.deepEqual(entry(store, 'a1'), {
|
||||
cell: gnssCellKey(50.1, 20.1),
|
||||
seenAt: 31 * MIN,
|
||||
degradedAt: null,
|
||||
});
|
||||
// Exactly one window after the degraded report it still counts.
|
||||
const edge = new Map();
|
||||
accumulateGnssObservations(edge, [report('a1', true)], 0);
|
||||
accumulateGnssObservations(edge, [report('a1', false)], 30 * MIN);
|
||||
assert.equal(entry(edge, 'a1').degradedAt, 0);
|
||||
});
|
||||
|
||||
test('rows are dated by the snapshot observation time, so a replay never restarts the window', () => {
|
||||
|
||||
Reference in new issue
Block a user