mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-15 15:52:21 +00:00
fix(cctv): warn once per failed background refresh; test the single flight
Attach the background-refresh warning where the refresh starts, so a failed refresh logs once instead of once per request served meanwhile. The test now checks that requests during a refresh share it, and turns the hang off before releasing the fetches so a retrying loader can't stall it. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
ca9dbea060
commit
5b12f51e98
2 files changed
+22
-10
No files matched your search
@@ -224,21 +224,22 @@ export function createCctvCatalog({ sourceRoot = process.cwd() } = {}) {
|
|||||||
_cctvSourceInflight = refreshCctvSources().finally(() => {
|
_cctvSourceInflight = refreshCctvSources().finally(() => {
|
||||||
_cctvSourceInflight = null;
|
_cctvSourceInflight = null;
|
||||||
});
|
});
|
||||||
|
// A background refresh has no caller waiting on it: report its failure
|
||||||
|
// here, once per refresh rather than once per request it serves.
|
||||||
|
if (_cctvSourceCache.length) {
|
||||||
|
_cctvSourceInflight.catch((error) => {
|
||||||
|
console.warn(
|
||||||
|
'[CCTV] background catalog refresh failed:',
|
||||||
|
error?.message || error,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// With a catalog in hand, answer with it while the refresh runs: the
|
// With a catalog in hand, answer with it while the refresh runs: the
|
||||||
// refresh lasts as long as the slowest pack (Tarktee's DATEX feeds take up
|
// refresh lasts as long as the slowest pack (Tarktee's DATEX feeds take up
|
||||||
// to its 30 s timeout), and every /api/cctv request would otherwise wait
|
// to its 30 s timeout), and every /api/cctv request would otherwise wait
|
||||||
// for it. Only the first load, with nothing to serve yet, waits.
|
// for it. Only the first load, with nothing to serve yet, waits.
|
||||||
if (_cctvSourceCache.length) {
|
return _cctvSourceCache.length ? _cctvSourceCache : _cctvSourceInflight;
|
||||||
_cctvSourceInflight.catch((error) => {
|
|
||||||
console.warn(
|
|
||||||
'[CCTV] background catalog refresh failed:',
|
|
||||||
error?.message || error,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
return _cctvSourceCache;
|
|
||||||
}
|
|
||||||
return _cctvSourceInflight;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -217,7 +217,18 @@ test('an expired catalog is served at once while a slow pack refreshes in the ba
|
|||||||
['old-0', 'old-1', 'old-2'],
|
['old-0', 'old-1', 'old-2'],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Requests during the refresh share it rather than starting another.
|
||||||
|
const pause = () => new Promise((resolve) => setTimeout(resolve, 50));
|
||||||
|
await pause();
|
||||||
|
const inFlight = hung.length;
|
||||||
|
assert.ok(inFlight > 0, 'the refresh reached the hanging upstreams');
|
||||||
|
await getSources();
|
||||||
|
await getSources();
|
||||||
|
await pause();
|
||||||
|
assert.equal(hung.length, inFlight, 'only one refresh ran');
|
||||||
|
|
||||||
// When the slow pack gives up, the refreshed catalog replaces the old one.
|
// When the slow pack gives up, the refreshed catalog replaces the old one.
|
||||||
|
hang = false;
|
||||||
for (const giveUp of hung) giveUp();
|
for (const giveUp of hung) giveUp();
|
||||||
for (let i = 0; i < 50; i += 1) {
|
for (let i = 0; i < 50; i += 1) {
|
||||||
const ids = (await getSources()).map((s) => s.id);
|
const ids = (await getSources()).map((s) => s.id);
|
||||||
|
|||||||
Reference in new issue
Block a user