fix(proxy): retain feature modules across tracing reconfiguration#9331
Conversation
Overall package sizeSelf size: 6.77 MB Dependency sizes| name | version | self size | total size | |------|---------|-----------|------------| | import-in-the-middle | 3.3.1 | 122.62 kB | 438.86 kB | | opentracing | 0.14.7 | 194.81 kB | 194.81 kB | | dc-polyfill | 0.1.11 | 25.74 kB | 25.74 kB |🤖 This report was automatically generated by heaviest-objects-in-the-universe |
🎉 All green!🧪 All tests passed 🎯 Code Coverage (details) 🔗 Commit SHA: 82fbf8e | Docs | Datadog PR Page | Give us feedback! |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #9331 +/- ##
==========================================
- Coverage 96.65% 96.64% -0.02%
==========================================
Files 923 923
Lines 122977 122993 +16
Branches 21408 21751 +343
==========================================
+ Hits 118861 118863 +2
- Misses 4116 4130 +14 Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
BenchmarksBenchmark execution time: 2026-07-15 14:54:35 Comparing candidate commit 82fbf8e in PR branch Found 0 performance improvements and 0 performance regressions! Performance is the same for 2320 metrics, 38 unstable metrics.
|
e86c187 to
8d8d4fc
Compare
| proxy._modules.openfeature.enable(config) | ||
| lazyProxy(proxy, 'openfeature', () => require('./flagging_provider'), tracer, config) | ||
| const openfeature = proxy._modules.openfeature | ||
| const shouldCreateProvider = openfeature.module === undefined |
There was a problem hiding this comment.
Looks similar to #9359
You check if undefined and I checked the provider properties of the public proxy.openfeature object
There was a problem hiding this comment.
I just combined both approaches, since your approach seemed more correct overall :)
…onfigure `Tracer#updateTracing` runs on the initial `init()` and again on every `APM_TRACING` remote-config update (via the reconfigure callback registered in `init`). The OpenFeature provider's `lazyProxy` was outside the `_tracingInitialized` guard, so in the non-serverless path `defineEagerly` reassigned `tracer.openfeature = new FlaggingProvider(...)` on each reconfigure. Consumers register the provider once with the OpenFeature SDK, e.g. `OpenFeature.setProvider(tracer.openfeature)`. When a remote-config update then replaces the instance, remote flag configuration is applied (via the FFE_FLAGS product handler's `() => this.openfeature`) to the new instance while the SDK keeps evaluating against the original, now-orphaned one. That orphaned provider never receives configuration, stays in its error/not-ready state, and evaluations fall back to defaults for the lifetime of the process. Move the provider creation inside the `_tracingInitialized` guard, alongside the other tracing SDKs (appsec/llmobs/aiguard), so it is created exactly once and the instance consumers registered keeps receiving remote config. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This makes sure OpenFeature exposure reporting and AI Guard integrations resume after remote config re-enables tracing, without replacing their public SDKs.
AI Guard remained disabled when a remote configuration restored tracing, leaving its SDK active without its feature module.
The generic proxy and the feature registration hook both created a provider during initial non-serverless setup, orphaning the first instance. Keep creation in the feature registration and gate it on the public provider so consumers remain bound to the object receiving FFE_FLAGS.
8d8d4fc to
82fbf8e
Compare
) Remote configuration that disables and re-enables tracing could leave OpenFeature consumers bound to an orphaned provider and leave AI Guard integrations unsubscribed. Preserve lazily initialized feature modules across reconfiguration and re-enable their integrations when tracing resumes. Co-authored-by: Bo Stendal Sørensen <[email protected]> Co-authored-by: Sameeran Kunche <[email protected]
) Remote configuration that disables and re-enables tracing could leave OpenFeature consumers bound to an orphaned provider and leave AI Guard integrations unsubscribed. Preserve lazily initialized feature modules across reconfiguration and re-enable their integrations when tracing resumes. Co-authored-by: Bo Stendal Sørensen <[email protected]> Co-authored-by: Sameeran Kunche <[email protected]
) Remote configuration that disables and re-enables tracing could leave OpenFeature consumers bound to an orphaned provider and leave AI Guard integrations unsubscribed. Preserve lazily initialized feature modules across reconfiguration and re-enable their integrations when tracing resumes. Co-authored-by: Bo Stendal Sørensen <[email protected]> Co-authored-by: Sameeran Kunche <[email protected]
) Remote configuration that disables and re-enables tracing could leave OpenFeature consumers bound to an orphaned provider and leave AI Guard integrations unsubscribed. Preserve lazily initialized feature modules across reconfiguration and re-enable their integrations when tracing resumes. Co-authored-by: Bo Stendal Sørensen <[email protected]> Co-authored-by: Sameeran Kunche <[email protected]
Summary
Remote configuration can disable and later re-enable tracing in one process. This retains the OpenFeature provider registered by callers, then restores OpenFeature exposure reporting and AI Guard integrations when tracing returns.