You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Changes dependent-flag evaluation to return detached prerequisite evaluation records and transactional exposure candidates after the root graph completes. The provider publishes prerequisite evaluations synchronously before returning the root result.
Motivation
Recursive-time telemetry callbacks can lose reached prerequisite records across failure boundaries and mix non-transactional evaluation telemetry with transactional exposures. A returned batch preserves failure telemetry while ensuring dependency exposures are emitted only after complete root success.
Additional Notes
Includes successful and failed reached prerequisites once, excluding the root.
Keeps memoized evaluations unique and parallel evaluations isolated.
Telemetry publication is best-effort and cannot affect assignment behavior.
Exposure candidates remain separate and are discarded when the root graph fails.
The reason will be displayed to describe this comment to others. Learn more.
🟡 Changes recommended
Unresolved dependency-handling issues can reject entire configuration updates on null keys, omit failure records for invalid depth limits, and cause avoidable evaluation overhead.
Adds dependent-flag graph evaluation to the OpenFeature provider, separating prerequisite evaluation telemetry from exposures so failure records can survive while exposures remain transactional.
Changes:
Parses prerequisite conditions and dependency-depth controls, and advertises CDN support.
Returns detached prerequisite records and exposure candidates, then processes them through provider hooks.
Adds coverage for graph failures, memoization, opt-out behavior, exposure rollback, and concurrent evaluations.
perf: Every initialized client evaluation reaches ExposureLoggingHook.before, allocating two thread-local scope stacks and their entries even for flags without dependencies; staging also constructs an empty trace (flag-with-confidence). Reuse cleared stack storage or evaluation-owned HookData where appropriate, and avoid empty trace allocations while preserving nested-call isolation. Verify the ordinary client path with an allocation-profiled benchmark; evaluateWideGraph bypasses these hooks.
Isolate nested evaluations from outer prerequisite traces
A nested evaluation of the same flag and EvaluationContext can read the outer batch if an earlier before hook throws before ExposureLoggingHook.before runs. The inner logging and metrics finally hooks then match the outer scope and republish its prerequisites, even though the inner evaluation never reached them. Bind trace lookup to an evaluation-specific lifecycle token and add a same-key/same-context skipped-before regression test.
Reuse one context snapshot across dependency exposures
perf: ExposureLoggingHook.finallyAfter → recordDependencyExposures → exposureEvent copies and flattens the context for every newly exposed dependency, retaining each copy in the queue (flag-with-confidence). Lazily capture one detached subject/attributes snapshot after the first eligible cache miss and reuse it across the batch. Verify allocations with a hook-level benchmark; evaluateWideGraph bypasses this path.
The reason will be displayed to describe this comment to others. Learn more.
🟡 Changes recommended
Unresolved lifecycle and configuration-snapshot bugs can discard prerequisite telemetry and exposures or leak thread-local scopes, while trace copying and repeated dependency scans add performance costs.
The description promises prerequisite publication before the provider returns the root result, but this only stages the batch: publication happens later in finallyAfter(), and direct provider calls publish nothing. Either publish evaluations at the stated provider boundary with best-effort isolation, keeping exposures transactional, or update the description to document client-hook-only publication after application hooks.
Avoid quadratic copying of dependency exposure traces
perf: Client evaluation through DDEvaluator.evaluate() → resolve() copies complete transitive exposure traces into each parent's memoized result. A root → N parents → shared hub → N leaves graph has O(N) nodes and edges but retains and replays O(N²) trace references. Share trace structure and flatten/deduplicate at commit while preserving rollback; verify with allocation profiling of this shared-subgraph shape, which the wide-sibling benchmarks do not cover.
The reason will be displayed to describe this comment to others. Learn more.
🟡 Changes recommended
Active issues cause missing prerequisite telemetry when opt-out is false or absent and allow unrelated flag evaluations to use stale pinned configurations, potentially returning FLAG_NOT_FOUND.
The reason will be displayed to describe this comment to others. Learn more.
🔵 Needs a closer look
Human assessment is needed because truncating evaluation time to milliseconds can change flag assignments at sub-millisecond allocation boundaries, creating a correctness risk.
Use returned graph telemetry, lifecycle-atomic exposures, evaluator-gated delivery, and compatibility-safe hook state.
Environment: Datadog workspace
Co-Authored-By: Codex GPT-5 <noreply@localhost>
This branch has not been deployed
No deployments
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
crucible: reviewingA Crucible review has started; this PR has reviewer attention.
3 participants
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What Does This Do
Changes dependent-flag evaluation to return detached prerequisite evaluation records and transactional exposure candidates after the root graph completes. The provider publishes prerequisite evaluations synchronously before returning the root result.
Motivation
Recursive-time telemetry callbacks can lose reached prerequisite records across failure boundaries and mix non-transactional evaluation telemetry with transactional exposures. A returned batch preserves failure telemetry while ensuring dependency exposures are emitted only after complete root success.
Additional Notes
Test Coverage
CanonicalFixtureTestcases require the uninitializedffe-system-test-datasubmodule.Jira ticket: N/A