fix: suppress Npcap SV catch-up bursts after scheduler lateness - #49
Conversation
|
Final validation:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 674d351017
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| var learnable = observedInterval >= MinimumLearnableIntervalTicks && | ||
| observedInterval <= MaximumLearnableIntervalTicks && | ||
| (nominalInterval <= 0 || observedInterval <= nominalInterval * 3); |
There was a problem hiding this comment.
Avoid learning the pacing rate from a late interval
When the thread is delayed between the first two frames, any gap from 20 µs through 5 ms is accepted as the nominal interval, even though it may be scheduler lateness rather than the requested rate. For example, a 4,000 fps publisher preempted for 1 ms after its first send learns 1 ms; subsequent pacing then enforces that interval, and because later observations are taken after pacing, the clock cannot converge back to 250 µs. This permanently reduces the wire rate while smpCnt and reference timestamps continue to represent the configured rate. Seed or update the estimate only from demonstrated steady intervals rather than accepting the first in-range observation.
AGENTS.md reference: AGENTS.md:L173-L178
Useful? React with 👍 / 👎.
| var isSampledValues = TryReadSampledValuesKey(frame.Span, out var streamKey); | ||
| if (isSampledValues) | ||
| await PaceSampledValuesAsync(streamKey, cancellationToken).ConfigureAwait(false); |
There was a problem hiding this comment.
Keep SV pacing from blocking unrelated traffic
When SV and PTP or GOOSE share this duplex transport, an SV call acquires the global send gate before awaiting its pacing deadline, so every unrelated frame is blocked for the remaining learned interval, potentially up to 5 ms. The inspected SV Publisher workflow does share this transport with the concurrent lab PTP publisher and peer-delay responder, meaning time-sensitive PTP responses can be delayed even though they are supposed to remain unpaced; pacing state needs separate synchronization from the short device-injection critical section.
AGENTS.md reference: AGENTS.md:L173-L178
Useful? React with 👍 / 👎.
Summary
Hardens live Sampled Values transmission when a Windows publisher thread is delayed by foreground UI load, window focus changes, GC or scheduler contention.
Problem
A deadline-driven publisher can become late and then call
SendAsyncrepeatedly while catching up. The existing Npcap transport injected every queued SV frame immediately, producing a micro-burst. On a local loopback adapter this could still overflow receiver/capture scheduling, exposingsmpCntgaps and unstable downstream waveform/phasor presentation.Change
Scope
Frame encoding,
smpCnt, reference timestamps, quality, APPID, VLAN and capture behavior are unchanged. This is a transport-level burst-suppression guard for best-effort Windows/Npcap laboratory publishing.