Split out of #803, which had to say this before it could explain what debounce is for. It stands on its own, it is unblocked, and it is docs-only.
The gap
throttle is leading-edge only: it emits the first value of a burst and suppresses the rest — including the last one. Neither doc site says so.
- The op rustdoc (
Throttle, crates/wingfoil/src/ops.rs — search pub struct Throttle) says "emits the first value, then suppresses until at least interval has passed since the last emit". That is the mechanism, stated accurately, but the reader has to derive the consequence themselves.
- The fluent method (
StreamOps::throttle, crates/wingfoil/src/fluent.rs) says only "Rate-limit: emit at most once per interval." That is actively misleading about which value you get — and the fluent doc is the one most readers actually see, because it is what shows up at the call site.
Why it matters: for "the user stopped typing", "the burst settled", "emit the final state after the storm", you want the trailing value. Someone reaching for a rate limiter picks it by name, gets the leading value, and nothing tells them.
The work
House model
Collapse's rustdoc, in the same file, is the model for this kind of warning — match its directness rather than hedging. Note in particular its observation that the loss only appears under load: a source producing one value per cycle never bursts, so throttle looks lossless in testing and starts dropping values exactly when the graph gets busy. The same is true here, and it is the part worth saying out loud.
Docs only — no behaviour change, no test changes expected. Branch from main, PR base main.
Split out of #803, which had to say this before it could explain what
debounceis for. It stands on its own, it is unblocked, and it is docs-only.The gap
throttleis leading-edge only: it emits the first value of a burst and suppresses the rest — including the last one. Neither doc site says so.Throttle,crates/wingfoil/src/ops.rs— searchpub struct Throttle) says "emits the first value, then suppresses until at leastintervalhas passed since the last emit". That is the mechanism, stated accurately, but the reader has to derive the consequence themselves.StreamOps::throttle,crates/wingfoil/src/fluent.rs) says only "Rate-limit: emit at most once perinterval." That is actively misleading about which value you get — and the fluent doc is the one most readers actually see, because it is what shows up at the call site.Why it matters: for "the user stopped typing", "the burst settled", "emit the final state after the storm", you want the trailing value. Someone reaching for a rate limiter picks it by name, gets the leading value, and nothing tells them.
The work
Throttle's rustdoc: name the contract (leading edge) and state the consequence — the last value of a burst is dropped unless it happens to fall outside the suppression window.StreamOps::throttle's doc comment: the same, in a line. "Emit at most once perinterval" alone is not enough to pick correctly.audit(window)— fixed-window trailing-edge rate limiting #928 (audit, fixed window) and Adddebounce(quiet_period)— trailing-edge rate limiting #803 (debounce, sliding window). If either has landed by the time you write this, link the op itself rather than the issue.House model
Collapse's rustdoc, in the same file, is the model for this kind of warning — match its directness rather than hedging. Note in particular its observation that the loss only appears under load: a source producing one value per cycle never bursts, sothrottlelooks lossless in testing and starts dropping values exactly when the graph gets busy. The same is true here, and it is the part worth saying out loud.Docs only — no behaviour change, no test changes expected. Branch from
main, PR basemain.