Conversation
|
18f7f00 to
508a8c8
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #3630 +/- ##
==========================================
- Coverage 62.21% 62.11% -0.11%
==========================================
Files 141 141
Lines 13387 13387
Branches 1753 1753
==========================================
- Hits 8329 8315 -14
- Misses 4260 4273 +13
- Partials 798 799 +1 see 3 files with indirect coverage changes Continue to review full report in Codecov by Sentry.
🚀 New features to boost your workflow:
|
ff84598 to
9f36eb7
Compare
7c43198 to
7bbed08
Compare
Benchmarks [ tracer ]Benchmark execution time: 2026-02-12 14:24:20 Comparing candidate commit 6bdc4f9 in PR branch Found 4 performance improvements and 40 performance regressions! Performance is the same for 147 metrics, 3 unstable metrics. scenario:ComposerTelemetryBench/benchTelemetryParsing
scenario:ContextPropagationBench/benchExtractHeaders128Bit
scenario:ContextPropagationBench/benchExtractHeaders128Bit-opcache
scenario:ContextPropagationBench/benchExtractHeaders64Bit
scenario:ContextPropagationBench/benchExtractTraceContext128Bit
scenario:ContextPropagationBench/benchExtractTraceContext128Bit-opcache
scenario:ContextPropagationBench/benchExtractTraceContext64Bit
scenario:ContextPropagationBench/benchInject128Bit
scenario:ContextPropagationBench/benchInject64Bit
scenario:EmptyFileBench/benchEmptyFileBaseline
scenario:EmptyFileBench/benchEmptyFileDdprof
scenario:EmptyFileBench/benchEmptyFileOverhead
scenario:HookBench/benchHookOverheadInstallHookOnFunction
scenario:HookBench/benchHookOverheadInstallHookOnMethod
scenario:HookBench/benchHookOverheadTraceFunction
scenario:HookBench/benchHookOverheadTraceMethod
scenario:HookBench/benchWithoutHook
scenario:LaravelBench/benchLaravelBaseline
scenario:LaravelBench/benchLaravelDdprof
scenario:LaravelBench/benchLaravelOverhead
scenario:MessagePackSerializationBench/benchMessagePackSerialization
scenario:PDOBench/benchPDOBaseline
scenario:PHPRedisBench/benchRedisBaseline
scenario:SamplingRuleMatchingBench/benchGlobMatching1
scenario:SamplingRuleMatchingBench/benchGlobMatching2
scenario:SamplingRuleMatchingBench/benchGlobMatching3
scenario:SamplingRuleMatchingBench/benchGlobMatching4
scenario:SamplingRuleMatchingBench/benchRegexMatching1
scenario:SamplingRuleMatchingBench/benchRegexMatching2
scenario:SamplingRuleMatchingBench/benchRegexMatching3
scenario:SamplingRuleMatchingBench/benchRegexMatching4
scenario:SpanBench/benchDatadogAPI
scenario:SymfonyBench/benchSymfonyBaseline
scenario:SymfonyBench/benchSymfonyDdprof
scenario:SymfonyBench/benchSymfonyOverhead
scenario:TraceAnnotationsBench/benchTraceAnnotationOverhead
scenario:TraceFlushBench/benchFlushTrace
scenario:TraceSerializationBench/benchSerializeTrace
|
## Motivation Add Feature Flagging and Experimentation (FFE) support to the remote config infrastructure, enabling tracers to subscribe to FFE_FLAGS configurations via the sidecar. WIP: php tracer changes (DataDog/dd-trace-php#3630) ## Changes - Add `FfeFlags` variant to `RemoteConfigProduct` enum - Add `"FFE_FLAGS"` string mapping in Display and FromStr - Add `FfeFlagConfigurationRules = 46` to `RemoteConfigCapabilities` - Add `FfeFlags(Vec<u8>)` variant to `RemoteConfigData` to preserve raw config bytes ## Decisions - Raw bytes are preserved (not parsed) in `FfeFlags(Vec<u8>)` since each tracer handles evaluation with the `datadog-ffe` crate directly - Capability bit 46 matches the server-side FFE capability definition Co-authored-by: leo.romanovsky <leo.romanovsky@datadoghq.com>
1990188 to
867337e
Compare
a24b1ae to
24e4304
Compare
Add FFE support to dd-trace-php. Flag evaluation is delegated to libdatadog's datadog-ffe Rust crate via FFI. PHP handles orchestration: config lifecycle, exposure dedup, and HTTP transport. Rust FFI layer (components-rs/ffe.rs): - C-callable bridge to datadog-ffe::rules_based - Global config store behind Mutex<FfeState> - Structured attribute passing (no JSON on hot path) C extension (ext/ddtrace.c): - ffe_evaluate, ffe_has_config, ffe_config_changed, ffe_load_config - Marshals PHP arrays to FfeAttribute structs Remote Config (components-rs/remote_config.rs): - Register FfeFlags product + FfeFlagConfigurationRules capability - Handle add/remove of FFE configs via sidecar PHP Provider (src/DDTrace/FeatureFlags/Provider.php): - Singleton checking RC config state - Calls native evaluate, parses JSON results - Reports exposures via LRU-deduplicated writer Exposure pipeline: - LRU cache (65K entries) with length-prefixed composite keys - Batched writer to /evp_proxy/v2/api/v2/exposures (1000 cap) - Auto-flush via register_shutdown_function OpenFeature adapter (src/DDTrace/OpenFeature/DataDogProvider.php): - Implements AbstractProvider for open-feature/sdk Build: - Add datadog-ffe to RUST_FILES in Makefile for PECL packaging - Cargo.lock: minimal additions only (73 new crates, no gratuitous bumps) - Bump libdatadog to ed316b638 (FFE RC support, libdatadog#1532) Tests: - LRU cache unit tests (11 tests) - Exposure cache unit tests (12 tests) - 220 evaluation correctness tests from JSON fixtures Config: DD_EXPERIMENTAL_FLAGGING_PROVIDER_ENABLED (default: false)
2a5d688 to
1ec323b
Compare
…OpenFeature layers - Add null check for flag_key in ddog_ffe_evaluate Rust FFI - Set variant in OpenFeature ResolutionDetails (was always null) - Replace magic numbers with named constants for reason/error codes - Fix json_decode null ambiguity in JSON type parsing with json_last_error() - Add dropped event tracking and curl failure logging (DD_TRACE_DEBUG) - Guard against missing curl extension in ExposureWriter flush - Fix buildEvent docblock parameter order
Motivation
Add FFE support to dd-trace-php. PHP applications can evaluate feature flags delivered via Remote Config using the same
datadog-ffeRust engine used by Ruby and Python.Changes
components-rs/ffe.rs): C-callable bridge todatadog-ffe::rules_based— config store, evaluate, result accessorsext/ddtrace.c):ffe_evaluate,ffe_has_config,ffe_config_changed,ffe_load_configinternal functions that marshal PHP arrays toFfeAttributestructscomponents-rs/remote_config.rs): RegisterFfeFlagsproduct +FfeFlagConfigurationRulescapability; handle add/remove of FFE configssrc/DDTrace/FeatureFlags/Provider.php): Singleton that checks RC config state, calls native evaluate, parses JSON results, reports exposures/evp_proxy/v2/api/v2/exposures(1000 event buffer cap)src/DDTrace/OpenFeature/DataDogProvider.php): ImplementsAbstractProviderfor theopen-feature/sdkcomposer packagedatadog-ffetoRUST_FILESin Makefile for PECL packagingDD_EXPERIMENTAL_FLAGGING_PROVIDER_ENABLEDgating via X-macro inext/configuration.hDecisions
Evaluation in Rust, not PHP. All flag evaluation (UFC parsing, targeting rules, shard hashing, allocation resolution) happens in
libdatadog'sdatadog-ffecrate via FFI. PHP only handles orchestration (config lifecycle, exposure dedup, HTTP transport). This matches Ruby and Python — no language re-implements evaluation logic.Global config behind
Mutex<FfeState>. The Rust FFE config is stored in alazy_staticglobal with aMutex. PHP is single-threaded per process, soRwLockwould be unnecessary complexity. Thechangedflag andconfigare bundled in one struct to avoid torn reads.Reuses existing RC pipeline. FFE configs flow through the same sidecar →
ddog_process_remote_configs()path as APM Tracing and Live Debugger. No new polling mechanism.Structured attributes, not JSON blobs. The C extension converts PHP arrays into
FfeAttributestructs (typed: string/number/bool) before calling Rust, avoiding JSON encode/decode overhead on the hot path.Exposure dedup uses length-prefixed composite keys. Key =
len(flag):flag:subject, value =len(variant):variant:allocation. Avoids collision from delimiters appearing in flag/subject strings.ExposureWriter caps at 1000 events per request. Matches Ruby and Python. Flush via
register_shutdown_function.Cargo.lock: minimal additions only. Started from master's lockfile and ran
cargo check— only 73 new crates added (datadog-ffe transitive deps), 2 unavoidable minor bumps (once_cell 1.20→1.21 required by pyo3, os_info 3.9→3.14 required by crashtracker). Noedition2024crates, no gratuitous upgrades.Test Results
Unit tests (local, no extension):
243 tests, 75 assertions, 1 skippedUnit tests (Docker with extension):
243 tests, 735 assertions — all passSystem tests (
FEATURE_FLAGGING_AND_EXPERIMENTATION, apache-mod-8.0):Cross-language dogfood parity (6 flags, 6 SDKs):
Companion PRs
LOC (excluding Cargo.lock + JSON fixtures)