Skip to content

feat(ffe): add native exposure lifecycle#3905

Closed
leoromanovsky wants to merge 1 commit into
leo.romanovsky/pr-i-remote-config-lifecyclefrom
leo.romanovsky/pr-j-exposure-lifecycle
Closed

feat(ffe): add native exposure lifecycle#3905
leoromanovsky wants to merge 1 commit into
leo.romanovsky/pr-i-remote-config-lifecyclefrom
leo.romanovsky/pr-j-exposure-lifecycle

Conversation

@leoromanovsky
Copy link
Copy Markdown

Motivation

This is PR J in the PHP OpenFeature/FFE stack. PR I wires Remote Config config delivery into the native evaluator; this slice adds native exposure buffering and lifecycle delivery so successful logged evaluations can be drained through the tracer sidecar.

Shared planning/reference doc: https://docs.google.com/document/d/1NvMfTpZWLBlFmEFNjdnlMyeVpy5l7KD8qujGFco6w2w/edit?tab=t.0

Reference implementation: #3630
Libdatadog dependency: DataDog/libdatadog#2026

Changes

  • Import ddog_sidecar_send_ffe_exposures from the libdatadog submodule and use it from ext/sidecar.c instead of implementing EVP sidecar forwarding in dd-trace-php.
  • Add native FFE exposure state in Rust with LRU deduplication, a capped batch buffer, service/env/version context, flush/free helpers, and fork reset.
  • Add PHP extension functions for enqueueing, flushing, setting exposure context, and resetting native exposure state.
  • Add NativeExposureWriter and make Client::create() use it by default when the extension functions are available.
  • Flush native exposure batches during request shutdown and sidecar shutdown, and reset copied exposure state after fork.
  • Add CODEOWNERS coverage for the libdatadog submodule and PHPT coverage for buffer drain/dedup and fork reset behavior.

Decisions

  • dd-trace-php owns only the PHP-facing event shaping and native lifecycle buffer; libdatadog owns the sidecar EVP proxy forwarding API.
  • NativeExposureWriter::flush() is intentionally a no-op because production delivery is owned by extension lifecycle hooks. Calling the test-only native flush function from userland would drain without forwarding to the sidecar.
  • The client still emits the transitional warning and reports productionRuntime => false until the remaining metrics and end-to-end activation slices land.
  • This PR depends on the libdatadog FFE sidecar forwarding PR landing before this submodule pointer can merge.

Validation

  • git diff --check
  • find src/api/FeatureFlags tests/api/Unit/FeatureFlags -name '*.php' -print0 | xargs -0 -n1 php -n -l
  • php -n -l tests/ext/ffe/flush_drains_buffer.phpt && php -n -l tests/ext/ffe/fork_resets_dedup.phpt && php -n -l ext/ddtrace.stub.php
  • vendor/bin/phpcs -s src/api/FeatureFlags tests/api/Unit/FeatureFlags
  • php -n vendor/bin/phpunit --config=phpunit.xml tests/api/Unit/FeatureFlags
  • vendor/bin/phpunit --config=phpunit.xml tests/api/Unit/FeatureFlags
  • RUSTC_BOOTSTRAP=1 cargo check -p ddtrace-php
  • RUSTC_BOOTSTRAP=1 cargo test -p ddtrace-php exposure_flush_drains_buffer_and_keeps_context
  • EXTRA_CFLAGS="-I$(brew --prefix pcre2)/include" EXTRA_LDFLAGS="-L$(brew --prefix pcre2)/lib" make -j"$(sysctl -n hw.ncpu)"
  • php -n -d extension=tmp/build_extension/modules/ddtrace.so -m | rg -i '^ddtrace$'
  • make test_c TESTS=tests/ext/ffe/flush_drains_buffer.phpt
  • make test_c TESTS=tests/ext/ffe/fork_resets_dedup.phpt
  • make test_c TESTS=tests/ext/ffe/native_bridge_evaluate.phpt
  • make test_c TESTS=tests/ext/ffe/remote_config_lifecycle.phpt skipped locally because request-replayer is unavailable outside the Datadog dev environment.

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

datadog-prod-us1-6 Bot commented May 22, 2026

Pipelines  Tests

Fix all issues with BitsAI

⚠️ Warnings

🚦 35 Pipeline jobs failed

DataDog/apm-reliability/dd-trace-php | ASAN test_c: [7.4, arm64]   View in Datadog   GitLab

🔧 Fix in code (Fix with Cursor). Memory leak detected in _dd_new_stack at coms.c:195. Aborted execution due to leak sanitizer.

🧪 1 Test failed

tmp/build_extension/tests/ext/ffe/fork_resets_dedup.phpt (FFE: fork handler resets exposure dedup in child) from PHP.tmp.build_extension.tests.ext.ffe   View in Datadog (Fix with Cursor)
004+ 
005+ =================================================================
006+ ==3927==ERROR: LeakSanitizer: detected memory leaks
007+ 
008+ Direct leak of 40 byte(s) in 1 object(s) allocated from:
009+     #0 0xe450b1a2c5cc in calloc (/usr/lib/llvm-19/lib/clang/19/lib/linux/libclang_rt.asan-aarch64.so+0x10c5cc) (BuildId: 01d185df05089232d2f28e13a020257065e55def)
010+     #1 0xe450a7dab934 in _dd_new_stack tmp/build_extension/ext/coms.c:195:35
011+     #2 0xe450a7dab6e0 in ddtrace_coms_minit tmp/build_extension/ext/coms.c:239:35
012+     #3 0xe450a7d8ea18 in dd_activate_once tmp/build_extension/ext/ddtrace.c:485:13
013+     #4 0xe450ae1f701c in __pthread_once_slow nptl/pthread_once.c:116:7
...

DataDog/apm-reliability/dd-trace-php | API unit tests: [7.0]   View in Datadog   GitLab

🔧 Fix in code (Fix with Cursor). 1 failed test in ClientTest.php: expected 'Datadog-backed PHP feature flag evaluation is not fully enabled yet.' but got 'Datadog-backed PHP feature flag evaluation is not fully production-ready yet.'

DataDog/apm-reliability/dd-trace-php | API unit tests: [7.1]   View in Datadog   GitLab

🔧 Fix in code (Fix with Cursor). 1 failed test in ClientTest.php: Failed asserting that two strings are identical at line 107.

View all 35 failed jobs.

ℹ️ Info

No other issues found (see more)

❄️ No new flaky tests detected

🎯 Code Coverage (details)
Patch Coverage: 100.00%
Overall Coverage: 60.74% (+0.00%)

Useful? React with 👍 / 👎

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

@pr-commenter
Copy link
Copy Markdown

pr-commenter Bot commented May 22, 2026

Benchmarks [ tracer ]

Benchmark execution time: 2026-05-22 02:45:01

Comparing candidate commit 9c7dcaf in PR branch leo.romanovsky/pr-j-exposure-lifecycle with baseline commit cae2759 in branch leo.romanovsky/pr-i-remote-config-lifecycle.

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

scenario:MessagePackSerializationBench/benchMessagePackSerialization-opcache

  • 🟩 execution_time [-8.737µs; -7.163µs] or [-7.993%; -6.553%]

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