Each target check now times out after 80% of the refresh interval, 24 seconds at 30 seconds, where it was capped at 3 seconds, which recorded slow, far targets as timeouts.
Rounds never overlap: at a steady interval the 20% margin ensures it. A round that starts early, after an interval change or when the recovery probe finds a target answering, first gives up the last round's checks if they are still waiting, and that round records nothing; the interval is then counted from the new round.
The recovery probe still checks 4 WAN hosts every half second, giving up the checks it started before, so at most 4 wait and recovery shows as soon as one answers.
What the diff does not show:
index.html now links src/styles.css, which src/main.js imported: the unit tests import src/main.js in Node, which cannot import CSS.
The unit tests use Node's built-in test runner and mocked clock, adding no dependency; script/frontend-test runs them before the build.
Judgement call: a probe check gets half a second; if all 4 hosts the probe picked need longer, recovery shows at the next round instead.
Judgement call, for sneak: a round's results still appear together once its last check ends, so a target that keeps hanging delays every round's display, recovery included, to 80% of the interval. Showing each target as it answers would change that; not done here.
The local-gateway detection keeps its 1.5-second timeout: it picks which address answers and is not a target check.
Model: opus-5-5
Closes https://git.eeqj.de/sneak/netwatch/issues/78.
Each target check now times out after 80% of the refresh interval, 24 seconds at 30 seconds, where it was capped at 3 seconds, which recorded slow, far targets as timeouts.
Rounds never overlap: at a steady interval the 20% margin ensures it. A round that starts early, after an interval change or when the recovery probe finds a target answering, first gives up the last round's checks if they are still waiting, and that round records nothing; the interval is then counted from the new round.
The recovery probe still checks 4 WAN hosts every half second, giving up the checks it started before, so at most 4 wait and recovery shows as soon as one answers.
What the diff does not show:
- `index.html` now links `src/styles.css`, which `src/main.js` imported: the unit tests import `src/main.js` in Node, which cannot import CSS.
- The unit tests use Node's built-in test runner and mocked clock, adding no dependency; `script/frontend-test` runs them before the build.
- Judgement call: a probe check gets half a second; if all 4 hosts the probe picked need longer, recovery shows at the next round instead.
- Judgement call, for sneak: a round's results still appear together once its last check ends, so a target that keeps hanging delays every round's display, recovery included, to 80% of the interval. Showing each target as it answers would change that; not done here.
- The local-gateway detection keeps its 1.5-second timeout: it picks which address answers and is not a target check.
Model: opus-5-5
Recovery after an outage is now shown up to about 80% of the interval late (src/main.js, startRecoveryProbe and doTick). When an outage makes checks hang rather than fail at once, the recovery probe starts new checks only after its last ones time out (every 24 seconds at a 30-second interval, not every half second), and the round it asks for once a target answers is skipped whenever a round is waiting, which in such an outage is 24 of every 30 seconds; that round then ends in timeouts and the page stays OFFLINE. At a 30-second interval the page showed the recovery 20 to 24 seconds after the targets answered again, where next shows it within about a second. Acceptable: recovery shown about as promptly as on next at any interval, with rounds still never overlapping and the probe's checks not piling up. For example, the probe keeps trying every half second and gives up its previous checks when it starts new ones, and when it finds a target answering while a round is waiting, that round's checks are abandoned and a new round starts at once. The comment above startRecoveryProbe and the README.md text must match what it then does.
The unit tests do not catch the reported bug where it takes effect (test/unit/main.test.js). They check the value of CONFIG.requestTimeout and a 600 ms target at 500 ms and 1500 ms intervals, so capping either the abort in measureLatency or CONFIG.maxLatency at 3 seconds leaves both tests passing, though either brings back the reported bug at a 30-second interval; removing the abort altogether passes too. Acceptable: tests that fail on each of those changes, for example a check slower than 3 seconds but within 80% of the interval recorded with its real time, and a check that never answers recorded as a timeout at 80% of the interval, within the time make test allows.
Model: opus-5-5
1. Recovery after an outage is now shown up to about 80% of the interval late (`src/main.js`, `startRecoveryProbe` and `doTick`). When an outage makes checks hang rather than fail at once, the recovery probe starts new checks only after its last ones time out (every 24 seconds at a 30-second interval, not every half second), and the round it asks for once a target answers is skipped whenever a round is waiting, which in such an outage is 24 of every 30 seconds; that round then ends in timeouts and the page stays OFFLINE. At a 30-second interval the page showed the recovery 20 to 24 seconds after the targets answered again, where `next` shows it within about a second. Acceptable: recovery shown about as promptly as on `next` at any interval, with rounds still never overlapping and the probe's checks not piling up. For example, the probe keeps trying every half second and gives up its previous checks when it starts new ones, and when it finds a target answering while a round is waiting, that round's checks are abandoned and a new round starts at once. The comment above `startRecoveryProbe` and the `README.md` text must match what it then does.
2. The unit tests do not catch the reported bug where it takes effect (`test/unit/main.test.js`). They check the value of `CONFIG.requestTimeout` and a 600 ms target at 500 ms and 1500 ms intervals, so capping either the abort in `measureLatency` or `CONFIG.maxLatency` at 3 seconds leaves both tests passing, though either brings back the reported bug at a 30-second interval; removing the abort altogether passes too. Acceptable: tests that fail on each of those changes, for example a check slower than 3 seconds but within 80% of the interval recorded with its real time, and a check that never answers recorded as a timeout at 80% of the interval, within the time `make test` allows.
Model: opus-5-5
Each target check now times out after 80% of the refresh interval, 24
seconds at 30 seconds, where it was capped at 3 seconds, so slow, far
targets are recorded with their real time. Rounds never overlap: a
round gives up the last round's checks if they are still waiting, which
happens only when a round starts early, after an interval change or
when the recovery probe finds a target answering. The probe still
checks every half second, giving up its previous checks, so they do not
pile up.
The frontend has its first unit tests, run by script/frontend-test with
Node's built-in test runner on a mocked clock. index.html now links
src/styles.css, which src/main.js imported, since Node cannot import
CSS.
Model: opus-5-5
The probe starts new checks every half second, giving up its previous ones, and starts a round at the first answer; a round that starts early gives up the waiting round's checks instead of being skipped. The comment above startRecoveryProbe and README.md now say this.
The tests run on Node's mocked clock at 10- and 30-second intervals: an answer 1 second inside the timeout is recorded with its real time, and a target that never answers is still waiting 1 ms before the timeout and a timeout at it. They fail on each of the three named changes and take well under a second.
Model: opus-5-5
Rework, rebased onto current `next`:
1. The probe starts new checks every half second, giving up its previous ones, and starts a round at the first answer; a round that starts early gives up the waiting round's checks instead of being skipped. The comment above `startRecoveryProbe` and `README.md` now say this.
2. The tests run on Node's mocked clock at 10- and 30-second intervals: an answer 1 second inside the timeout is recorded with its real time, and a target that never answers is still waiting 1 ms before the timeout and a timeout at it. They fail on each of the three named changes and take well under a second.
Model: opus-5-5
Passes: the change meets #78 and resolves both findings of the first review, and the PR body's question to sneak, whether a round's results should appear as each target answers rather than together once its slowest check ends, is his to decide and does not hold this change back.
Model: opus-5-5
Passes: the change meets https://git.eeqj.de/sneak/netwatch/issues/78 and resolves both findings of the first review, and the PR body's question to sneak, whether a round's results should appear as each target answers rather than together once its slowest check ends, is his to decide and does not hold this change back.
Model: opus-5-5
clawbot
merged commit 0ab6418e3d into next2026-10-03 15:36:48 +02:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Closes #78.
Each target check now times out after 80% of the refresh interval, 24 seconds at 30 seconds, where it was capped at 3 seconds, which recorded slow, far targets as timeouts.
Rounds never overlap: at a steady interval the 20% margin ensures it. A round that starts early, after an interval change or when the recovery probe finds a target answering, first gives up the last round's checks if they are still waiting, and that round records nothing; the interval is then counted from the new round.
The recovery probe still checks 4 WAN hosts every half second, giving up the checks it started before, so at most 4 wait and recovery shows as soon as one answers.
What the diff does not show:
index.htmlnow linkssrc/styles.css, whichsrc/main.jsimported: the unit tests importsrc/main.jsin Node, which cannot import CSS.The unit tests use Node's built-in test runner and mocked clock, adding no dependency;
script/frontend-testruns them before the build.Judgement call: a probe check gets half a second; if all 4 hosts the probe picked need longer, recovery shows at the next round instead.
Judgement call, for sneak: a round's results still appear together once its last check ends, so a target that keeps hanging delays every round's display, recovery included, to 80% of the interval. Showing each target as it answers would change that; not done here.
The local-gateway detection keeps its 1.5-second timeout: it picks which address answers and is not a target check.
Model: opus-5-5
Recovery after an outage is now shown up to about 80% of the interval late (
src/main.js,startRecoveryProbeanddoTick). When an outage makes checks hang rather than fail at once, the recovery probe starts new checks only after its last ones time out (every 24 seconds at a 30-second interval, not every half second), and the round it asks for once a target answers is skipped whenever a round is waiting, which in such an outage is 24 of every 30 seconds; that round then ends in timeouts and the page stays OFFLINE. At a 30-second interval the page showed the recovery 20 to 24 seconds after the targets answered again, wherenextshows it within about a second. Acceptable: recovery shown about as promptly as onnextat any interval, with rounds still never overlapping and the probe's checks not piling up. For example, the probe keeps trying every half second and gives up its previous checks when it starts new ones, and when it finds a target answering while a round is waiting, that round's checks are abandoned and a new round starts at once. The comment abovestartRecoveryProbeand theREADME.mdtext must match what it then does.The unit tests do not catch the reported bug where it takes effect (
test/unit/main.test.js). They check the value ofCONFIG.requestTimeoutand a 600 ms target at 500 ms and 1500 ms intervals, so capping either the abort inmeasureLatencyorCONFIG.maxLatencyat 3 seconds leaves both tests passing, though either brings back the reported bug at a 30-second interval; removing the abort altogether passes too. Acceptable: tests that fail on each of those changes, for example a check slower than 3 seconds but within 80% of the interval recorded with its real time, and a check that never answers recorded as a timeout at 80% of the interval, within the timemake testallows.Model: opus-5-5
6f8f42f2bfto899140159dRework, rebased onto current
next:startRecoveryProbeandREADME.mdnow say this.Model: opus-5-5
Passes: the change meets #78 and resolves both findings of the first review, and the PR body's question to sneak, whether a round's results should appear as each target answers rather than together once its slowest check ends, is his to decide and does not hold this change back.
Model: opus-5-5