feat(payload): adopt Probability for ValueConf::float_probability#1878
feat(payload): adopt Probability for ValueConf::float_probability#1878goxberry wants to merge 1 commit into
Conversation
|
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
This stack of pull requests is managed by Graphite. Learn more about stacking. |
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0c1423ac1f
ℹ️ 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".
| fn default() -> Self { | ||
| Self { | ||
| float_probability: 0.5, // 50% | ||
| float_probability: Probability::try_new(0.5).expect("0.5 is in [0.0, 1.0]"), |
There was a problem hiding this comment.
Remove the panic path from the default config
The repository instructions for /workspace/lading explicitly say production code must not use .unwrap() or .expect(), but this new default value adds an .expect() in ValueConf::default. Even though the current literal is valid, this leaves a panic path in production initialization and violates the no-panic invariant for config construction; prefer a non-panicking constant/helper for the known-valid default probability.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Hmm hmm hmm same comment as in #1877 (comment) but here it's 50%. This may just be a limit of Rust's type system we have to accept.
9f7f336 to
106f2ca
Compare
0c1423a to
809f4f4
Compare
106f2ca to
91a7f3b
Compare
809f4f4 to
0797961
Compare
Change `ValueConf::float_probability` from `f32` to the `Probability` alias
of `BoundedProbability<{ f32::to_bits(0.0) }>`. The `try_from` impl enforces
the finite + `[0.0, 1.0]` invariant at deserialize time; `ValueConf::new`
now takes the validated type directly. (`ValueConf::valid` already had no
finite/range check on this field, so nothing is removed there.)
The new type threads through `NumValueGenerator`'s `Constant` and `Uniform`
variants. At the two comparison sites in `<NumValueGenerator as Generator>::
generate`, `.get()` extracts the inner `f32` so RNG sequences and bit-exact
output are preserved.
Verified: `cargo test -p lading-payload` (250 pass). `cargo bench -p
lading-payload --bench dogstatsd --baseline pr1` shows ±2-6% swings across
all throughput sizes; the unrelated `cache_*` benches in `--bench block`
show similar magnitude run-to-run variance, so the delta is noise rather
than a real effect.
91a7f3b to
2905d45
Compare
0797961 to
8f98d9a
Compare
blt
left a comment
There was a problem hiding this comment.
+1 here with one comment that is shared in the parent. Choice in parent will resolve the nit here.

What does this PR do?
Switches
ValueConf::float_probabilityfrom baref32toProbability(
BoundedProbability<{ f32::to_bits(0.0) }>from #1876). Thetry_fromimpl enforces finite +
[0.0, 1.0]at deserialize time, and the publicconstructor
ValueConf::newnow takes the validated type directly.(
ValueConf::valid()already had no finite/range check on this field, sonothing is removed there.) The new type threads through
NumValueGenerator'sConstantandUniformvariants; at the twocomparison sites in
<NumValueGenerator as Generator>::generate,.get()extracts the inner
f32so RNG draws and bit-exact output are preserved.Motivation
Phase 1, PR 2 of the stacked rollout planned in #1876 — wire
BoundedProbabilityaliases intolading_payloadconfigs one field at atime, smallest blast radius first. After
TimestampConfig::probability(#1877),
ValueConf::float_probabilityis the next smallest: it touchesonly
dogstatsd.rsanddogstatsd/common.rs, andValueConfisconstructed via
DefaultorValueConf::new(no test fixtures build itwith a struct literal), so the change stays localized.
Moving the validation into the type means an invalid
float_probabilityis rejected at parse time with a structured error instead of silently
accepted (the existing
valid()never checked it); the in-code field canno longer hold a value outside
[0.0, 1.0].Related issues
Stacked on #1877 (PR 1:
TimestampConfig::probability), which itself sitsatop #1876 (Phase 0). Remaining fields in this rollout:
Config::sampling_probability,Config::multivalue_pack_probability,Config::unique_tag_ratio(viaAtLeastOneHundredth).Additional Notes
Wire format unchanged.
Probabilityserializes as a baref32viaserde(into = "f32", try_from = "f32"), so YAML/JSON configs writtenfor the previous field type continue to parse.
Public API breakage at
ValueConf::new. The constructor signaturechanges from
new(float_probability: f32, ...)tonew(float_probability: Probability, ...). The field is private, soexternal callers that build
ValueConfgo throughnew,Default, ordeserialization. There are no in-tree callers of
ValueConf::new.No sampler swap. The hot-path comparison stays
OpenClosed01.sample(rng) < float_probability.get();.get()is aconst fnreturning a copied scalar and inlines away.Default value preserved.
Default for ValueConfnow constructsProbability::try_new(0.5).expect("0.5 is in [0.0, 1.0]")in place ofthe bare
0.5.Bench delta.
cargo bench -p lading-payload --bench dogstatsd --baseline pr1(baseline saved from feat(payload): adopt Probability for TimestampConfig::probability #1877's tip):dogstatsd_setup: −0.29% (within 95% CI of zero)dogstatsd_throughput/1 MiB: −5.6%dogstatsd_throughput/10 MiB: −2.5%dogstatsd_throughput/100 MiB: −4.8%dogstatsd_throughput/1 GiB: −5.0%All deltas are favorable or neutral. The
--bench blockrun against thesame
pr1baseline shows ±1-5% swings oncache_*benches that don'ttouch any code in this PR, which sets the noise floor — the
dogstatsd_throughput"improvements" fall in the same band and areconsistent with run-to-run variance rather than a real speedup.