Skip to content

feat(ffe): support immediate subject experimentation opt-out - #4336

Draft
leoromanovsky wants to merge 7 commits into
masterfrom
leoromanovsky/experimentation-opt-out-immediate
Draft

leoromanovsky wants to merge 7 commits into
masterfrom
leoromanovsky/experimentation-opt-out-immediate

Conversation

@leoromanovsky

@leoromanovsky leoromanovsky commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Motivation

Customers need to exclude individual subjects from experimentation while continuing ordinary feature delivery.

Changes and Decisions

Set DD_FEATURE_FLAGS_EXPERIMENTATION_OPT_OUT_MODE=immediate to honor each subject's dd_experimentation_opt_out_at timestamp. The default is disabled.

use DDTrace\OpenFeature\DataDogProvider;
use OpenFeature\OpenFeatureAPI;
use OpenFeature\implementation\flags\Attributes;
use OpenFeature\implementation\flags\EvaluationContext;

// Configure DD_FEATURE_FLAGS_EXPERIMENTATION_OPT_OUT_MODE=immediate.
$api = OpenFeatureAPI::getInstance();
$api->setProvider(new DataDogProvider());
$attributes = [];
if ($athlete->experimentationOptOutAt !== null) {
    $attributes['dd_experimentation_opt_out_at'] =
        $athlete->experimentationOptOutAt->format(DATE_RFC3339_EXTENDED);
}
$enabled = $api->getClient('strava')->getBooleanValue(
    'new-route-planner',
    false,
    new EvaluationContext($athlete->id, new Attributes($attributes))
);

The evaluator skips allocations with doLog=true before matching or randomization. Evaluation continues through ordinary allocations. If none match, it returns the application's default.

Invalid timestamps return the default with INVALID_CONTEXT. Missing attributes preserve current behavior. Future timestamps take effect immediately.

Explicit constructor configuration overrides the environment setting. Each client resolves its mode once. This does not disable evaluation telemetry or emit new exposure types.

Depends on libdatadog #2698. The shared-fixture reader consumes the merged capability cases from ffe-system-test-data #49.

Validation

Tested commit Validation Result
DataDog/dd-trace-php@a7b4f291671d59d6c76263c4e33b3e6202c45e7c System tests: Remote Configuration, opt-out modes, fallbacks, exposure deduplication, and evaluation metrics; PHP 8.2, Linux/arm64 Not completed. Local Docker storage has a containerd I/O error.
DataDog/dd-trace-php@c25ade2a9f0b8e22937eb60edd57f80c7a4aea79 System tests: unset, disabled, and immediate modes; Remote Configuration, fallbacks, invalid context, deduplication, and OTLP evaluation metrics; PHP 8.2, Linux/arm64 Earlier commit passed three cases. Exposure counts: 5/5/2. A separate PHPT preflight probe segfault remains unisolated.

@datadog-official

datadog-official Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

Tests

🎉 All green!

🧪 All tests passed
❄️ No new flaky tests detected

🎯 Code Coverage (details)
• Patch Coverage: 100.00%
• Overall Coverage: 68.39% (-0.04%)

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: a7b4f29 | Docs | View more details | Give us feedback!

@pr-commenter

pr-commenter Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

Benchmarks [ tracer ]

Benchmark execution time: 2026-10-20 23:29:50

Comparing candidate commit a7b4f29 in PR branch leoromanovsky/experimentation-opt-out-immediate with baseline commit 77c6cf6 in branch master.

📊 Benchmarking dashboard

Found 2 performance improvements and 2 performance regressions! Performance is the same for 190 metrics, 0 unstable metrics.

Explanation

This is an A/B test comparing a candidate commit's performance against that of a baseline commit. Performance changes are noted in the tables below as:

  • 🟩 = significantly better candidate vs. baseline
  • 🟥 = significantly worse candidate vs. baseline

We compute a confidence interval (CI) over the relative difference of means between metrics from the candidate and baseline commits, considering the baseline as the reference.

If the CI is entirely outside the configured SIGNIFICANT_IMPACT_THRESHOLD (or the deprecated UNCONFIDENCE_THRESHOLD), the change is considered significant.

Feel free to reach out to #apm-benchmarking-platform on Slack if you have any questions.

More details about the CI and significant changes

You can imagine this CI as a range of values that is likely to contain the true difference of means between the candidate and baseline commits.

CIs of the difference of means are often centered around 0%, because often changes are not that big:

---------------------------------(------|---^--------)-------------------------------->
                              -0.6%    0%  0.3%     +1.2%
                                 |          |        |
         lower bound of the CI --'          |        |
sample mean (center of the CI) -------------'        |
         upper bound of the CI ----------------------'

As described above, a change is considered significant if the CI is entirely outside the configured SIGNIFICANT_IMPACT_THRESHOLD (or the deprecated UNCONFIDENCE_THRESHOLD).

For instance, for an execution time metric, this confidence interval indicates a significantly worse performance:

----------------------------------------|---------|---(---------^---------)---------->
                                       0%        1%  1.3%      2.2%      3.1%
                                                  |   |         |         |
       significant impact threshold --------------'   |         |         |
                      lower bound of CI --------------'         |         |
       sample mean (center of the CI) --------------------------'         |
                      upper bound of CI ----------------------------------'

scenario:MessagePackSerializationBench/benchMessagePackSerialization

  • 🟥 execution_time [+3.797µs; +5.003µs] or [+3.525%; +4.643%]

scenario:MessagePackSerializationBench/benchMessagePackSerialization-opcache

  • 🟥 execution_time [+4.618µs; +9.382µs] or [+4.179%; +8.491%]

scenario:SamplingRuleMatchingBench/benchRegexMatching2

  • 🟩 execution_time [-97.830ns; -47.970ns] or [-6.159%; -3.020%]

scenario:SamplingRuleMatchingBench/benchRegexMatching3

  • 🟩 execution_time [-139.972ns; -65.828ns] or [-8.627%; -4.057%]

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.

1 participant