Skip to content

fix: race condition between status check and provider lookup#108

Open
NeaguGeorgiana23 wants to merge 2 commits into
mainfrom
race_condttion
Open

fix: race condition between status check and provider lookup#108
NeaguGeorgiana23 wants to merge 2 commits into
mainfrom
race_condttion

Conversation

@NeaguGeorgiana23

Copy link
Copy Markdown
Contributor

This PR

Resolves the race condition between the provider status check and the provider lookup during flag evaluation.

To ensure thread-safety and consistent evaluation state under concurrent provider swaps, this PR refactors the evaluation flow to retrieve the provider and its status atomically:

Updates ClientAPI::EvaluateFlag to retrieve the FeatureProviderStatusManager atomically from the repository in a single locked operation.
Uses this single manager instance as the sole source of truth for both the status check and the provider retrieval, ensuring they are always consistent.
Guarantees that even if a concurrent provider swap occurs (via SetProvider), the ongoing evaluation safely completes using the consistent state of the provider that was active when the evaluation started.

Related Issues

Fixes #69

Signed-off-by: NeaguGeorgiana23 <neagugeorgiana@google.com>
@NeaguGeorgiana23 NeaguGeorgiana23 requested review from a team as code owners June 23, 2026 12:38
@coderabbitai

coderabbitai Bot commented Jun 23, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

ClientAPI::EvaluateFlag in openfeature/client_api.h is updated to obtain provider status through provider_repository_.GetFeatureProviderStatusManager(domain_) instead of GetProviderStatus(). A new early-return path is added: if no status manager is found for the domain, the method immediately returns ResolutionDetailsType with Reason::kError and ErrorCode::kProviderFatal.

Changes

Provider Status Lookup Fix

Layer / File(s) Summary
Provider status resolution in EvaluateFlag
openfeature/client_api.h
Replaces GetProviderStatus() with GetFeatureProviderStatusManager(domain_) followed by manager->GetStatus(). Adds an early-return guard that produces a fatal provider error when the status manager is absent for the client's domain.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~5 minutes

Possibly related PRs

  • open-feature/cpp-sdk#96: Modifies the same ClientAPI::EvaluateFlag provider-state handling path, changing how ProviderStatus is checked and what error codes are returned for specific provider states.

Suggested reviewers

  • oxddr
  • toddbaert
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: fixing a race condition between status check and provider lookup, which aligns with the PR's primary objective and the changes made.
Description check ✅ Passed The description is directly related to the changeset, clearly explaining the race condition being fixed and how the solution addresses it through atomic retrieval of the FeatureProviderStatusManager.
Linked Issues check ✅ Passed The PR successfully addresses the unchecked race condition item in #69 by refactoring ClientAPI::EvaluateFlag to atomically retrieve the FeatureProviderStatusManager, ensuring consistent status checks and provider lookups.
Out of Scope Changes check ✅ Passed All changes are within scope: the modification to ClientAPI::EvaluateFlag directly addresses the race condition objective without introducing unrelated modifications.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@openfeature/client_api.h`:
- Around line 116-125: The code obtains a FeatureProviderStatusManager instance
from the repository to check status, but then re-queries the repository
separately to get the provider, which creates a race condition where a
concurrent SetProvider call could change the provider between these two
operations, causing status and the evaluated provider to diverge. Instead of
calling the repository twice, reuse the same FeatureProviderStatusManager
instance obtained from provider_repository_.GetFeatureProviderStatusManager to
retrieve both the status and the provider, ensuring they remain consistent and
come from the same logical snapshot.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a1ac1b09-ef8b-415d-9743-577b73b80634

📥 Commits

Reviewing files that changed from the base of the PR and between 9c99e7b and 212e050.

📒 Files selected for processing (1)
  • openfeature/client_api.h

Comment thread openfeature/client_api.h
Signed-off-by: NeaguGeorgiana23 <neagugeorgiana@google.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors ClientAPI::EvaluateFlag to eliminate a race where provider status could be checked against one provider while the evaluation call used another provider after a concurrent SetProvider swap. It does this by retrieving a single FeatureProviderStatusManager instance from the repository and using it as the consistent source for both status and provider lookup during evaluation.

Changes:

  • Update ClientAPI::EvaluateFlag to fetch a FeatureProviderStatusManager once and use it for both GetStatus() and GetProvider().
  • Add an explicit error-return path when no status manager can be obtained for the domain.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread openfeature/client_api.h
Comment on lines +116 to +122
std::shared_ptr<FeatureProviderStatusManager> manager =
provider_repository_.GetFeatureProviderStatusManager(domain_);
if (!manager) {
return std::make_unique<ResolutionDetailsType>(
default_value, Reason::kError, std::nullopt, FlagMetadata(),
ErrorCode::kProviderFatal,
"Provider status manager not found for domain");
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.

Specification Compliance Review

2 participants