Show route churn as a whole count per minute (closes #160) #169

Merged
clawbot merged 1 commits from issue-160-churn-per-minute into next 2026-10-27 00:14:25 +01:00
Collaborator

Fixes #160.

The old figure was a correct average. Each announced or withdrawn prefix counted once, and the answer was the one-minute moving average per second. A quiet feed therefore gave a fraction such as 0.1.

What changed:

  • The metrics tracker counts prefix announcements and withdrawals, from all peers, in each clock minute, such as 12:04:00 to 12:05:00. It reports the count for the minute that ended most recently.
  • /api/v1/stats reports that count as route_churn_per_min in stream. The moving average route_churn_per_sec is gone.
  • The status page shows "Route Churn/min" with thousands separators.
  • The other per-second counts on /status and "Updates/sec" on / are rounded to whole numbers. Throughput keeps its decimals.
  • README describes the new field under /api/v1/stats.

Disclosures:

  • Judgement call: the brief named /status.json too, but it has no stream object and never carried the churn figure. Both pages read /api/v1/stats, so only that answer changed.
  • Judgement call: the README named no churn field before; I added one sentence for the new one.
  • The first figure after a start covers only the part of its minute the daemon was running.

Model: opus-5-5

Fixes https://git.eeqj.de/sneak/routewatch/issues/160. The old figure was a correct average. Each announced or withdrawn prefix counted once, and the answer was the one-minute moving average per second. A quiet feed therefore gave a fraction such as 0.1. What changed: - The metrics tracker counts prefix announcements and withdrawals, from all peers, in each clock minute, such as 12:04:00 to 12:05:00. It reports the count for the minute that ended most recently. - `/api/v1/stats` reports that count as `route_churn_per_min` in `stream`. The moving average `route_churn_per_sec` is gone. - The status page shows "Route Churn/min" with thousands separators. - The other per-second counts on `/status` and "Updates/sec" on `/` are rounded to whole numbers. Throughput keeps its decimals. - README describes the new field under `/api/v1/stats`. Disclosures: - Judgement call: the brief named `/status.json` too, but it has no `stream` object and never carried the churn figure. Both pages read `/api/v1/stats`, so only that answer changed. - Judgement call: the README named no churn field before; I added one sentence for the new one. - The first figure after a start covers only the part of its minute the daemon was running. Model: opus-5-5
clawbot added the needs-review label 2026-10-26 23:52:30 +01:00
clawbot self-assigned this 2026-10-26 23:52:30 +01:00
Author
Collaborator

FAIL: needs-rework

  1. internal/metrics/minutecounter_internal_test.go, TestChurnPerMinuteCountsLastFullMinute: this test does not cover the gap of several minutes. The jump from 12:02:00 to 12:04:00 comes after a minute with no events, so it gives 0 whether or not moveToCurrentMinute checks for a gap. No test depends on the branch that sets the last minute's count to 0 after a gap. Acceptable: record at least one prefix in a minute, make no call during the next minute, then read two or more minutes later and expect 0.

  2. README.md, the added sentence "stream.route_churn_per_min counts the prefixes announced or withdrawn in the last full minute of the clock.": it reads as a count of distinct prefixes. The figure counts every prefix in every update from every peer, so one prefix announced by 300 peers counts 300 times. "Minute of the clock" is also an odd way to say "clock minute". Acceptable: one short, accurate sentence, such as "stream.route_churn_per_min is the number of prefix announcements and withdrawals, from all peers, in the last full clock minute."

Judgement call: the README's opening sentence runs past 30 words, but this change does not touch it, so it is not a finding here.

Model: opus-5-5

**FAIL: needs-rework** 1. `internal/metrics/minutecounter_internal_test.go`, `TestChurnPerMinuteCountsLastFullMinute`: this test does not cover the gap of several minutes. The jump from 12:02:00 to 12:04:00 comes after a minute with no events, so it gives 0 whether or not `moveToCurrentMinute` checks for a gap. No test depends on the branch that sets the last minute's count to 0 after a gap. Acceptable: record at least one prefix in a minute, make no call during the next minute, then read two or more minutes later and expect 0. 2. `README.md`, the added sentence "`stream.route_churn_per_min` counts the prefixes announced or withdrawn in the last full minute of the clock.": it reads as a count of distinct prefixes. The figure counts every prefix in every update from every peer, so one prefix announced by 300 peers counts 300 times. "Minute of the clock" is also an odd way to say "clock minute". Acceptable: one short, accurate sentence, such as "`stream.route_churn_per_min` is the number of prefix announcements and withdrawals, from all peers, in the last full clock minute." Judgement call: the README's opening sentence runs past 30 words, but this change does not touch it, so it is not a finding here. Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-10-27 00:01:41 +01:00
clawbot added 1 commit 2026-10-27 00:05:10 +01:00
The status page showed route churn per second as a one-minute moving
average, so a quiet feed gave a fraction such as 0.1. The average was
correct.

The metrics tracker now also counts prefix announcements and
withdrawals, from all peers, in each clock minute. /api/v1/stats
reports the count for the last full minute as route_churn_per_min in
stream, in place of route_churn_per_sec. The status page shows it as
"Route Churn/min".

The status and home pages round messages and updates per second to
whole numbers.

Model: opus-5-5
clawbot force-pushed issue-160-churn-per-minute from f021cbd7c6 to dcf2e8aa3d 2026-10-27 00:05:10 +01:00 Compare
clawbot added needs-review and removed needs-rework labels 2026-10-27 00:05:36 +01:00
Author
Collaborator

Reworked against the review in #169 (comment):

  1. Fixed: the test now records a withdrawal at 12:04, makes no call during 12:05, reads at 12:06 and expects 0; it fails when the gap check in moveToCurrentMinute is removed.
  2. Fixed: the README sentence now reads "stream.route_churn_per_min is the number of prefix announcements and withdrawals, from all peers, in the last full clock minute." The code comments, the TODO.md entry, the commit message and the PR body use the same wording.

Model: opus-5-5

Reworked against the review in https://git.eeqj.de/sneak/routewatch/pulls/169#issuecomment-157020: 1. Fixed: the test now records a withdrawal at 12:04, makes no call during 12:05, reads at 12:06 and expects 0; it fails when the gap check in `moveToCurrentMinute` is removed. 2. Fixed: the README sentence now reads "`stream.route_churn_per_min` is the number of prefix announcements and withdrawals, from all peers, in the last full clock minute." The code comments, the `TODO.md` entry, the commit message and the PR body use the same wording. Model: opus-5-5
Author
Collaborator

PASS: both findings from #169 (comment) are fixed, and the change meets the plan in #160 (comment).

Judgement call: /status.json never carried the churn figure, so leaving it unchanged is correct.

Model: opus-5-5

**PASS**: both findings from https://git.eeqj.de/sneak/routewatch/pulls/169#issuecomment-157020 are fixed, and the change meets the plan in https://git.eeqj.de/sneak/routewatch/issues/160#issuecomment-156593. Judgement call: `/status.json` never carried the churn figure, so leaving it unchanged is correct. Model: opus-5-5
clawbot merged commit 355cd37496 into next 2026-10-27 00:14:25 +01:00
clawbot deleted branch issue-160-churn-per-minute 2026-10-27 00:14:25 +01:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/routewatch#169