docs: the five reseq probe cases as this build measures them, plus the overflow counter's reading
Re-measured all four recorded cases and added a fifth for the re-plan path, which needs 100 kS/s: at 10 kS/s the ring already covers 838 s, so no window the control can reach moves time_stride and the window probe re-plans nothing. Also notes that `stale` is 0 by construction while resequencing is on, and that the reservation cap is counted in packets, so its sample cost scales with the batch. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
d2d4b7f204
commit
210d124814
3 files changed
+111
-48
No files matched your search
+58
-32
@@ -201,58 +201,84 @@ as distinct from the fault injection below, which exercises ingest:
|
||||
- `--quiet-at S` freezes `sine` at its held value from stream second `S` onwards, so it stops
|
||||
crossing zero: the dropout trigger's input.
|
||||
|
||||
- `UDPSCOPE_PROBE_RESEQ_MS` — one mid-run reading of the resequencing path. Four cases,
|
||||
**run each as its own process** — four back to back starve the mock past its 2 s silence
|
||||
- `UDPSCOPE_PROBE_RESEQ_MS` — one mid-run reading of the resequencing path. Five cases,
|
||||
**run each as its own process** — five back to back starve the mock past its 2 s silence
|
||||
timeout and every case then reads a reconnect instead of what it was testing. Common
|
||||
conditions for all four: the mock at `--rate 10000 --batch 100 --freq 5`, udpscope with
|
||||
conditions for the first four: the mock at `--rate 10000 --batch 100 --freq 5`, udpscope with
|
||||
no extra options, under `xvfb-run` with
|
||||
`UDPSCOPE_EXIT_AFTER_MS=8000 UDPSCOPE_ENABLE_ALL_MS=600 UDPSCOPE_EXIT_DUMP=1
|
||||
UDPSCOPE_PROBE_RESEQ_MS=5000`.
|
||||
UDPSCOPE_PROBE_RESEQ_MS=5000`. Delete `~/.config/udpscope/127.0.0.1_8000.toml` first: a
|
||||
session left by an earlier run restores its math channel, and five channels instead of four
|
||||
change `channels=`, `span=` and every count derived from them.
|
||||
|
||||
| case | mock extra flags | key reading |
|
||||
| --- | --- | --- |
|
||||
| **base** | *(none)* | every counter 0; proves the machinery costs nothing |
|
||||
| **reorder** | `--reorder-every 10` | `reseq=51` (mid-run) / `102` (dump); `holes=0`; resequencing inside the window leaves no reservation |
|
||||
| **late** | `--reorder-every 10 --reorder-delay-ms 50` | `holes=42 bands=42 bands_repaired=42 nan_slots=0`; every band is the faint, repaired tier |
|
||||
| **mixed** | `--drop-every 20 --reorder-every 10 --reorder-delay-ms 50` | `bands=42 bands_repaired=20 nan_slots=2300`; all three band states at once |
|
||||
| **late** | `--reorder-every 10 --reorder-delay-ms 50` | `bands_repaired` one short of `bands` with `nan_slots=100`; the band still solid is the one hole whose late packet is in flight, and it is the *only* unrepaired one |
|
||||
| **mixed** | `--drop-every 20 --reorder-every 10 --reorder-delay-ms 50` | `bands=43 bands_repaired=20 nan_slots=2200`; all three band states at once |
|
||||
| **re-plan** | `--rate 100000` with the `mixed` flags, and `UDPSCOPE_PROBE_WINDOW_MS=4000 UDPSCOPE_PROBE_RESEQ_MS=6000 UDPSCOPE_EXIT_AFTER_MS=9000` | four `buffer rebuilt` lines before the reading, then `bands=64 bands_repaired=16 nan_slots=7800`: **a band is still only marked repaired when its own slots hold values**. A `bands_repaired == bands` beside a non-zero `nan_slots` here is the hole table and the producer's `tick_` surviving a re-plan that reset `produced()` — a band marked settled over samples that are all still NaN. The non-zero `overflows` is this case too: 100 kS/s with a 50 ms reorder delay keeps about 50 packets in flight against 64 slots |
|
||||
|
||||
Full measured readings (probe line first, then exit-dump; `bands_repaired` was added after the
|
||||
original probe and any earlier reading without it is obsolete):
|
||||
The re-plan case needs `--rate 100000`, not the other four's 10 000: at 10 kS/s the ring
|
||||
already covers 838 s, so no window the control can reach moves `time_stride`,
|
||||
`set_target_span()` returns without rebuilding, and the window probe reports `decim=1`
|
||||
throughout — it re-plans nothing. At 100 kS/s the ring covers 83.9 s and the probe's
|
||||
500 ms → 500 s → 120 s → 600 s → 60 s walk crosses the boundary four times.
|
||||
|
||||
Full measured readings (probe line first, then exit-dump):
|
||||
|
||||
```
|
||||
=== base mock: none
|
||||
[reseq-probe] reseq=0 late=0 stale=0 holes=0 hole_slots=0 backfilled=0 open_holes=0 bands=0
|
||||
bands_repaired=0 nan_slots=0 scanned=44000 trigger_in_hole=0
|
||||
[udpscope] frames=1024 packets=1025 gaps=0 channels=4 span=838.861s stride=1 reseq=0 late=0
|
||||
stale=0 holes=0 hole_slots=0 backfilled=0
|
||||
[udpscope] channel 0 'sine' stored=95200 published=95000
|
||||
[reseq-probe] reseq=0 late=0 stale=0 overflows=0 holes=0 hole_slots=0 backfilled=0 open_holes=0
|
||||
bands=0 bands_repaired=0 nan_slots=0 scanned=44200 trigger_in_hole=0
|
||||
[udpscope] frames=1032 packets=1033 gaps=0 channels=4 span=838.861s stride=1 reseq=0 late=0
|
||||
stale=0 overflows=0 holes=0 hole_slots=0 backfilled=0
|
||||
[udpscope] channel 0 'sine' stored=95700 published=95400
|
||||
|
||||
=== reorder mock: --reorder-every 10
|
||||
[reseq-probe] reseq=51 late=0 stale=0 holes=0 hole_slots=0 backfilled=0 open_holes=0 bands=0
|
||||
bands_repaired=0 nan_slots=0 scanned=44000 trigger_in_hole=0
|
||||
[udpscope] frames=1028 packets=1029 gaps=0 channels=4 span=838.861s stride=1 reseq=102 late=0
|
||||
stale=0 holes=0 hole_slots=0 backfilled=0
|
||||
[udpscope] channel 0 'sine' stored=95400 published=95100
|
||||
[reseq-probe] reseq=51 late=0 stale=0 overflows=0 holes=0 hole_slots=0 backfilled=0
|
||||
open_holes=0 bands=0 bands_repaired=0 nan_slots=0 scanned=44200
|
||||
trigger_in_hole=0
|
||||
[udpscope] frames=1027 packets=1028 gaps=0 channels=4 span=838.861s stride=1 reseq=102 late=0
|
||||
stale=0 overflows=0 holes=0 hole_slots=0 backfilled=0
|
||||
[udpscope] channel 0 'sine' stored=95300 published=95100
|
||||
|
||||
=== late mock: --reorder-every 10 --reorder-delay-ms 50
|
||||
[reseq-probe] reseq=142 late=48 stale=0 holes=42 hole_slots=4200 backfilled=16800 open_holes=42
|
||||
bands=42 bands_repaired=42 nan_slots=0 scanned=44000 trigger_in_hole=0
|
||||
[udpscope] frames=1026 packets=1027 gaps=100 channels=4 span=838.861s stride=1 reseq=288
|
||||
late=100 stale=0 holes=94 hole_slots=9400 backfilled=37600
|
||||
[udpscope] channel 0 'sine' stored=95700 published=95500
|
||||
[reseq-probe] reseq=157 late=46 stale=0 overflows=0 holes=40 hole_slots=4000 backfilled=15600
|
||||
open_holes=40 bands=40 bands_repaired=39 nan_slots=100 scanned=44000
|
||||
trigger_in_hole=0
|
||||
[udpscope] frames=1027 packets=1028 gaps=98 channels=4 span=838.861s stride=1 reseq=296
|
||||
late=98 stale=0 overflows=0 holes=91 hole_slots=9100 backfilled=36400
|
||||
[udpscope] channel 0 'sine' stored=95300 published=95000
|
||||
|
||||
=== mixed mock: --drop-every 20 --reorder-every 10 --reorder-delay-ms 50
|
||||
[reseq-probe] reseq=163 late=24 stale=0 holes=43 hole_slots=4300 backfilled=8000 open_holes=43
|
||||
bands=42 bands_repaired=20 nan_slots=2300 scanned=44100 trigger_in_hole=0
|
||||
[udpscope] frames=974 packets=975 gaps=101 channels=4 span=838.861s stride=1 reseq=314 late=50
|
||||
stale=0 holes=94 hole_slots=9400 backfilled=18400
|
||||
[udpscope] channel 0 'sine' stored=95100 published=94900
|
||||
[reseq-probe] reseq=159 late=25 stale=0 overflows=0 holes=43 hole_slots=4300 backfilled=8400
|
||||
open_holes=43 bands=43 bands_repaired=20 nan_slots=2200 scanned=44100
|
||||
trigger_in_hole=0
|
||||
[udpscope] frames=978 packets=981 gaps=101 channels=4 span=838.861s stride=1 reseq=309 late=50
|
||||
stale=0 overflows=0 holes=94 hole_slots=9400 backfilled=18400
|
||||
[udpscope] channel 0 'sine' stored=95400 published=95400
|
||||
|
||||
=== re-plan mock: --rate 100000 --drop-every 20 --reorder-every 10 --reorder-delay-ms 50
|
||||
[reseq-probe] reseq=4374 late=72 stale=0 overflows=36 holes=315 hole_slots=31136
|
||||
backfilled=26800 open_holes=64 bands=64 bands_repaired=16 nan_slots=7800
|
||||
scanned=156600 trigger_in_hole=0
|
||||
[udpscope] frames=8949 packets=8953 gaps=614 channels=4 span=83.886s stride=1 reseq=8028
|
||||
late=144 stale=0 overflows=36 holes=603 hole_slots=59936 backfilled=55600
|
||||
[udpscope] channel 0 'sine' stored=588600 published=584600
|
||||
```
|
||||
|
||||
The `mixed` case's `open_holes=43` against `bands=42` is correct: the 43rd hole has scrolled
|
||||
out of the visible window, and `build_invalid_spans()` drops a span outside the window rather
|
||||
than pinning it to the edge. The per-field reference is in
|
||||
[probe-readings.md](probe-readings.md).
|
||||
The `late` case's `bands_repaired` is one short of `bands` with `nan_slots=100` — exactly one
|
||||
packet's worth of slots at stride 1 — because the probe fires 50 ms-delayed releases into a
|
||||
window that always has one in flight. An earlier recording of this case read
|
||||
`bands_repaired=42 nan_slots=0`; both are healthy, and which one a run gets is where the
|
||||
probe's instant falls relative to the newest release. A `bands_repaired` *above* the count of
|
||||
holes whose slots hold values is the defect, in either direction.
|
||||
|
||||
`holes` far above `open_holes` in the re-plan case is the two bounds working: a re-plan clears
|
||||
the table (the old entries address a buffer that is gone) and `kMaxHoles` caps what survives
|
||||
at 64. The `mixed` case's `open_holes=43` against `bands=43` has no such spread because
|
||||
nothing re-planned. The per-field reference is in [probe-readings.md](probe-readings.md).
|
||||
|
||||
The mock also carries three **fault injections** that no probe schedules, because what they exercise
|
||||
is the ingest rather than the UI. The first: `--time-glitch-at <stream seconds> --time-glitch-by <seconds>` makes
|
||||
|
||||
Reference in new issue
Block a user