Skip to content

Per-descriptor rate ceilings; make within-transfer Block2 pacing conditional on measured ceiling #10

Description

@QuiteYellow

Follow-up from PR #8 review. Consolidates original follow-up items 2 and 3 into one piece of work, per the review discussion.

Background. PR #8 landed inter-request pacing to avoid RT-OCF request drops, plus the residual-pace() optimization. Two open questions remained:

  • (orig. item 2) Drop within-transfer Block2 pacing entirely?
  • (orig. item 3) Replace the _DEFAULT_RATE_LIMIT_RPS = 5.0 floor with each descriptor's measured ceiling.

The measurement evidence on dropping within-transfer pacing was inconclusive: on a marginal device (dishwasher, 10.0.0.129) an interleaved 40-sweep test showed 2/60 hrefs failing paced vs 5/60 unpaced, but non-significant (Fisher's exact p≈0.44), and the failures were 3 clustered /device/0 congestion events — not 60 independent trials — where the paced sweep also failed in two of the three. So within-transfer pacing could not be shown to help or be shown safe to remove on that device class. Rather than drop it globally on a "should be safe" basis, we fold the decision into the per-descriptor ceiling work.

Plan.

  1. Plumb per-device rate first — this isn't a constant swap. bridge.py:237 constructs DtlsCoapSession(...) without passing rate_limit_rps, so every device currently runs at the _DEFAULT_RATE_LIMIT_RPS = 5.0 default; the measured ceilings live only as comments above the PollTier lists (samples/dryer.py, samples/oven.py), not as a descriptor field. Add a rate field to the descriptor and have the bridge pass it into DtlsCoapSession(rate_limit_rps=...), keeping _DEFAULT_RATE_LIMIT_RPS as the fallback when a descriptor omits it. (Values come from the descriptors — the 3 frozen samples here plus those localthings maintains; the library keeps the 5.0 floor.)
  2. Set each descriptor's ceiling (oven ~8 rps → 125 ms, dryer ~14 rps → 71 ms) so inter-poll spacing in PollScheduler._do_tier is not over-conservative.
  3. Make within-transfer Block2 pacing (if num > 0: self.pace() in DtlsCoapSession.get()) conditional on the measured per-device ceiling rather than unconditional — keep it for devices whose ceiling warrants it, skip it where measured headroom shows continuation GETs are not throttled.
  4. Re-verify multi-block /device/0 on characterized hardware (oven/dryer, fridge/dishwasher) after the change.

Acceptance. Per-descriptor ceilings drive both inter-poll and within-transfer pacing; no regression in Block2 completion on the four characterized appliances; marginal devices (dishwasher) retain their within-transfer insurance.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions