fix(system): keep worker telemetry polling live
This commit is contained in:
@@ -24,6 +24,7 @@ test("Worker 006 telemetry remains a bounded system feature slice", async () =>
|
||||
contourSettings,
|
||||
contourContract,
|
||||
pollIntervalContract,
|
||||
pollingScheduler,
|
||||
telemetryStyles,
|
||||
styles,
|
||||
] = await Promise.all([
|
||||
@@ -40,6 +41,7 @@ test("Worker 006 telemetry remains a bounded system feature slice", async () =>
|
||||
read("components/system/ComputeContourSettingsWindow.tsx"),
|
||||
read("core/system/computeContours.ts"),
|
||||
read("core/system/telemetryPollInterval.ts"),
|
||||
read("core/system/sequentialPolling.ts"),
|
||||
read("styles/system-telemetry.css"),
|
||||
read("styles.css"),
|
||||
]);
|
||||
@@ -109,6 +111,9 @@ test("Worker 006 telemetry remains a bounded system feature slice", async () =>
|
||||
);
|
||||
assert.match(pollIntervalContract, /MIN_TELEMETRY_POLL_INTERVAL_SECONDS\s*=\s*1/);
|
||||
assert.match(telemetryPolling, /normalizeWorkerTelemetryPollMilliseconds/);
|
||||
assert.match(telemetryPolling, /startSequentialPolling/);
|
||||
assert.doesNotMatch(telemetryPolling, /if\s*\(\s*!enabled\s*\|\|\s*loading\s*\)/);
|
||||
assert.match(pollingScheduler, /A transient failure must not stop polling/);
|
||||
assert.match(styles, /system-telemetry\.css/);
|
||||
});
|
||||
|
||||
@@ -145,3 +150,59 @@ test("MQTT polling interval keeps an unrestricted draft until explicit commit",
|
||||
assert.equal(contract.normalizeWorkerTelemetryPollMilliseconds(100), 1_000);
|
||||
assert.equal(contract.normalizeWorkerTelemetryPollMilliseconds(3_000), 3_000);
|
||||
});
|
||||
|
||||
test("Worker telemetry polling repeats after fast responses and transient errors", async () => {
|
||||
const source = await read("core/system/sequentialPolling.ts");
|
||||
const javascript = ts.transpileModule(source, {
|
||||
compilerOptions: {
|
||||
module: ts.ModuleKind.ES2022,
|
||||
target: ts.ScriptTarget.ES2022,
|
||||
},
|
||||
}).outputText;
|
||||
const polling = await import(
|
||||
`data:text/javascript;base64,${Buffer.from(javascript).toString("base64")}`
|
||||
);
|
||||
|
||||
let nextHandle = 1;
|
||||
const timers = new Map();
|
||||
const cleared = [];
|
||||
const scheduler = {
|
||||
setTimeout(callback, delayMilliseconds) {
|
||||
const handle = nextHandle++;
|
||||
timers.set(handle, { callback, delayMilliseconds });
|
||||
return handle;
|
||||
},
|
||||
clearTimeout(handle) {
|
||||
cleared.push(handle);
|
||||
timers.delete(handle);
|
||||
},
|
||||
};
|
||||
let attempts = 0;
|
||||
const stop = polling.startSequentialPolling(async () => {
|
||||
attempts += 1;
|
||||
if (attempts === 2) throw new Error("transient");
|
||||
}, 3_000, scheduler);
|
||||
|
||||
await new Promise((resolve) => setImmediate(resolve));
|
||||
assert.equal(attempts, 1);
|
||||
assert.equal(timers.size, 1);
|
||||
assert.equal([...timers.values()][0].delayMilliseconds, 3_000);
|
||||
|
||||
let [handle, scheduled] = [...timers.entries()][0];
|
||||
timers.delete(handle);
|
||||
scheduled.callback();
|
||||
await new Promise((resolve) => setImmediate(resolve));
|
||||
assert.equal(attempts, 2);
|
||||
assert.equal(timers.size, 1, "a transient error must schedule the next poll");
|
||||
|
||||
[handle, scheduled] = [...timers.entries()][0];
|
||||
timers.delete(handle);
|
||||
scheduled.callback();
|
||||
await new Promise((resolve) => setImmediate(resolve));
|
||||
assert.equal(attempts, 3);
|
||||
assert.equal(timers.size, 1);
|
||||
|
||||
stop();
|
||||
assert.equal(timers.size, 0);
|
||||
assert.deepEqual(cleared, [nextHandle - 1]);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user