Skip to content

feat(payload): adopt Probability for ValueConf::float_probability#1878

Open
goxberry wants to merge 1 commit into
goxberry/probability-timestamp-configfrom
goxberry/probability-value-conf-float
Open

feat(payload): adopt Probability for ValueConf::float_probability#1878
goxberry wants to merge 1 commit into
goxberry/probability-timestamp-configfrom
goxberry/probability-value-conf-float

Conversation

@goxberry
Copy link
Copy Markdown
Contributor

@goxberry goxberry commented May 21, 2026

What does this PR do?

Switches ValueConf::float_probability from bare f32 to Probability
(BoundedProbability<{ f32::to_bits(0.0) }> from #1876). The try_from
impl enforces finite + [0.0, 1.0] at deserialize time, and the public
constructor 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 draws and bit-exact output are preserved.

Motivation

Phase 1, PR 2 of the stacked rollout planned in #1876 — wire
BoundedProbability aliases into lading_payload configs one field at a
time, smallest blast radius first. After TimestampConfig::probability
(#1877), ValueConf::float_probability is the next smallest: it touches
only dogstatsd.rs and dogstatsd/common.rs, and ValueConf is
constructed via Default or ValueConf::new (no test fixtures build it
with a struct literal), so the change stays localized.

Moving the validation into the type means an invalid float_probability
is rejected at parse time with a structured error instead of silently
accepted (the existing valid() never checked it); the in-code field can
no longer hold a value outside [0.0, 1.0].

Related issues

Stacked on #1877 (PR 1: TimestampConfig::probability), which itself sits
atop #1876 (Phase 0). Remaining fields in this rollout: Config::sampling_probability,
Config::multivalue_pack_probability, Config::unique_tag_ratio (via
AtLeastOneHundredth).

Additional Notes

  • Wire format unchanged. Probability serializes as a bare f32 via
    serde(into = "f32", try_from = "f32"), so YAML/JSON configs written
    for the previous field type continue to parse.

  • Public API breakage at ValueConf::new. The constructor signature
    changes from new(float_probability: f32, ...) to
    new(float_probability: Probability, ...). The field is private, so
    external callers that build ValueConf go through new, Default, or
    deserialization. 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 a
    const fn returning a copied scalar and inlines away.

  • Default value preserved. Default for ValueConf now constructs
    Probability::try_new(0.5).expect("0.5 is in [0.0, 1.0]") in place of
    the 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 block run against the
    same pr1 baseline shows ±1-5% swings on cache_* benches that don't
    touch any code in this PR, which sets the noise floor — the
    dogstatsd_throughput "improvements" fall in the same band and are
    consistent with run-to-run variance rather than a real speedup.

Copy link
Copy Markdown
Contributor Author

goxberry commented May 21, 2026

@datadog-datadog-prod-us1
Copy link
Copy Markdown

datadog-datadog-prod-us1 Bot commented May 21, 2026

Pipelines

Fix all issues with BitsAI

⚠️ Warnings

🚦 1 Pipeline job failed

Changelog Check | changelog-check   View in Datadog   GitHub Actions

🛟 This job is unlikely to succeed on retry. Please review your pipeline configuration. No changes to CHANGELOG.md detected. Add 'no-changelog' label if this is intentional.

Useful? React with 👍 / 👎

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 8f98d9a | Docs | Datadog PR Page | Give us feedback!

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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]"),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@goxberry goxberry force-pushed the goxberry/probability-timestamp-config branch from 9f7f336 to 106f2ca Compare May 21, 2026 05:44
@goxberry goxberry force-pushed the goxberry/probability-value-conf-float branch from 0c1423a to 809f4f4 Compare May 21, 2026 05:44
@goxberry goxberry force-pushed the goxberry/probability-timestamp-config branch from 106f2ca to 91a7f3b Compare May 21, 2026 06:34
@goxberry goxberry force-pushed the goxberry/probability-value-conf-float branch from 809f4f4 to 0797961 Compare May 21, 2026 06:34
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.
@goxberry goxberry force-pushed the goxberry/probability-timestamp-config branch from 91a7f3b to 2905d45 Compare May 21, 2026 06:47
@goxberry goxberry force-pushed the goxberry/probability-value-conf-float branch from 0797961 to 8f98d9a Compare May 21, 2026 06:47
Copy link
Copy Markdown
Collaborator

@blt blt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 here with one comment that is shared in the parent. Choice in parent will resolve the nit here.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants