Repository navigation
feat(openfeature): harden provider lifecycle and delivery recovery - #6323
Conversation
|
✅ All CI checks and tests passed. 🎉 All green!🧪 All tests passed 🎯 Code Coverage (details) 🔗 Commit SHA: a1607ad | Docs | View more details | Give us feedback! |
Typing analysisNote: Ignored files are excluded from the next sections. Untyped methodsThis PR introduces 2 partially typed methods, and clears 1 partially typed method. It increases the percentage of typed methods from 72.05% to 72.09% (+0.04%). Partially typed methods (+2-1)❌ Introduced:Untyped other declarationsThis PR introduces 1 partially typed other declaration, and clears 1 partially typed other declaration. It increases the percentage of typed other declarations from 86.23% to 86.29% (+0.06%). Partially typed other declarations (+1-1)❌ Introduced:If you believe a method or an attribute is rightfully untyped or partially typed, you can add |
BenchmarksBenchmark execution time: 2026-09-28 12:27:36 Comparing candidate commit 3c2db4f in PR branch Found 0 performance improvements and 0 performance regressions! Performance is the same for 52 metrics, 0 unstable metrics.
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ef1bbff293
ℹ️ About Codex in GitHub
Codex has been enabled to automatically 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 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
leoromanovsky
left a comment
There was a problem hiding this comment.
initruns asynchronously, but shutdown doesn’t set a terminal/cancelled state. If provider A is replaced by B while A is still waiting for configuration, A can later call activation and overwrite B as the delivery target. A may then emitREADYafter shutdown, while B stops receiving lifecycle events. See provider.rb and activation.rb. Add a shutdown tombstone/cancellation check before activation and after waiting, plus coverage for shutdown-before-activation and shutdown-while-waiting.
This contradicts the OpenFeature shutdown requirement to end in NOT_READY. The Go provider guards against post-shutdown initialization; Java tears down its evaluator. The new STALE → READY recovery behavior otherwise aligns with Go’s lifecycle semantics.
@leoromanovsky thank you for pointing this. Fixed. Provider shutdown now sets a terminal tombstone and coordinates with activation under the components lock. Added deterministic coverage for shutdown-before-activation and shutdown-while-waiting. |
|
Module naming inconsistency: Settings now live under To be explicit about scope: this means moving the whole module to Suggested target for the provider:
If the module name is fixed by the cross-SDK spec, disregard — question raised on #6291. |
Strech
left a comment
There was a problem hiding this comment.
This PR lacks OOP design and require some common Ruby adjustments. The signs of missing abstractions are:
- Use of
a, b = mutex dostatements, that looks like a copy from Go-lang where the tuple return is a design pattern - Mixed responsibilities between Configuration, Events and Provider events everything, boarders quite blurry
- Deeply nested
if/elseconditions - Enormous amount of state/events definitions inside the Provider class, but unrelated to provider perse
Strech
left a comment
There was a problem hiding this comment.
For the testing - some Ruby/RSpec hygiene is required. Most of the violations related to definitions, but there are some misuses or testing approaches to be corrected too
|
@TonyCTHsu Thanks—this is a reasonable consistency improvement. I’d prefer not to fold the full namespace migration into this lifecycle stack: Datadog::OpenFeature::Provider and the datadog/open_feature/provider require path predate these PRs and are already shipped API, while feature_flags names the Datadog product settings and OpenFeature names the integration surface. The stale settings reference was fixed and covered as a configuration call-site issue. I suggest handling a canonical Datadog::FeatureFlags::OpenFeatureProvider separately, with compatibility aliases, require-path shims, and an explicit deprecation plan. |
435dbb4 to
a1607ad
Compare
#6403) Revert PR #6323 (994bde1) before PR #6295 (65dca5e), because the lifecycle changes depend on the activation layer. Restore compatibility with the existing Ruby parametric server, which aborts when feature flags start remote configuration before its startup guard. Preserve the later OTLP export marker change.
* origin/master: (177 commits) Fix flaky: native transport fork drain spec (#6380) Fix symbol extraction for instrumented methods (#6339) Mark trace transport provenance at export [🤖] Lock Dependency: https://github.com/DataDog/dd-trace-rb/actions/runs/36876578516 Make standardrb happy Add changelog entry [PROF-16128] Profiling: Fix native extension build breaking when trying to log % Dependency inject args into configure_libdatadog docs: add instructions for updating system-tests commit SHA in CI configurations (#6405) ci: adopt LLM validation gate for AGENTS.md Add stable OTel environment attribute mapping (#6261) Revert OpenFeature provider activation and dependent lifecycle changes (#6403) Declare FLAKY_BENCHMARKS_REGEX and document benchmarks CI (#6369) feat(openfeature): harden provider lifecycle and delivery recovery (#6323) feat(openfeature): activate delivery during provider initialization (#6295) feat(openfeature): add agentless configuration delivery (#6294) feat(openfeature): track configuration delivery readiness (#6292) feat(openfeature): add agentless configuration and source resolution (#6291) adding TODO comment for otlp export Change TAG_SDK_OTLP_EXPORT type from ::String to String ...
What does this PR do?
Hardens Datadog OpenFeature provider and configuration-delivery lifecycles. It preserves Remote Configuration state across provider replacement, restarts Remote Configuration and agentless delivery after forks, emits ready, changed, and stale provider events, and synchronizes runtime Remote Configuration registration.
It also pins the system-tests workflow to the agentless configuration-source coverage introduced by DataDog/system-tests#7683.
Motivation:
This hardening was extracted from #6295 into a fifth focused PR to keep each layer reviewable. The complete feature is intentionally split across five stacked PRs and will be merged atomically, starting from the last PR.
Change log entry
None. The customer-facing agentless configuration-delivery entry is included in #6295.
Additional Notes:
Warning
This is PR 5 of a 5-PR stack. It depends on code from all four parent PRs and must not be merged directly into
master.Merge the stack last-to-first: #6323 into #6295, #6295 into #6294, #6294 into #6292, #6292 into #6291, and finally #6291 into
master.The split exists only to allow focused reviews; the five PRs form one atomic feature.
How to test the change?
StandardRB, full Steep type checking, and actionlint pass. The OpenFeature rake suite passes on Ruby 3.1 and Ruby 4.0. Agentless configuration-source coverage is provided by DataDog/system-tests#7683.