fix: race condition between status check and provider lookup#108
fix: race condition between status check and provider lookup#108NeaguGeorgiana23 wants to merge 2 commits into
Conversation
Signed-off-by: NeaguGeorgiana23 <neagugeorgiana@google.com>
📝 WalkthroughWalkthrough
ChangesProvider Status Lookup Fix
Estimated code review effort🎯 2 (Simple) | ⏱️ ~5 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
Comment |
There was a problem hiding this comment.
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
📒 Files selected for processing (1)
openfeature/client_api.h
Signed-off-by: NeaguGeorgiana23 <neagugeorgiana@google.com>
There was a problem hiding this comment.
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::EvaluateFlagto fetch aFeatureProviderStatusManageronce and use it for bothGetStatus()andGetProvider(). - 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.
| 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"); |
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