feat(remote-config): add RemoteConfigSourceProvider for source failover#3667
feat(remote-config): add RemoteConfigSourceProvider for source failover#3667ajpallares wants to merge 4 commits into
Conversation
Add the address book that hands out the current healthy api and blob sources and fails over to the next one when a source is reported unhealthy. Each purpose fails over independently, sources are deduped by url and ordered once via WeightedSourceSelector, and a stale unhealthy report (identified by url) cannot advance the provider twice. Mirrors the iOS RemoteConfigSourceProvider. Co-authored-by: Cursor <cursoragent@cursor.com>
Drop the RemoteConfigSources wrapper in favor of apiSources/blobSources constructor params, and replace currentApiSource/currentBlobSource with a single getCurrent(purpose) keyed by purpose, consistent with restart(purpose). Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Conflicting priority/weight on a shared URL signals misconfigured input, a degraded state better surfaced via warnLog than debugLog. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 6e5556e. Configure here.
| // moved past (e.g. from a concurrent caller) no longer matches, so it can't advance twice. | ||
| if (selector.current?.url != url) return | ||
| selector.advance() | ||
| } |
There was a problem hiding this comment.
Restart revives consumed handle reports
Medium Severity
reportUnhealthy treats a handle as current whenever its url matches selector.current, but restart() rewinds the iterator without invalidating handles that already advanced failover once. Reporting the same handle after restart() can advance again (e.g. a → b) even though that handle’s unhealthy report was already applied, skipping a fresh attempt at the first source.
Reviewed by Cursor Bugbot for commit 6e5556e. Configure here.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3667 +/- ##
==========================================
+ Coverage 80.34% 80.38% +0.03%
==========================================
Files 382 383 +1
Lines 15706 15752 +46
Branches 2191 2200 +9
==========================================
+ Hits 12619 12662 +43
- Misses 2213 2214 +1
- Partials 874 876 +2 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|


Checklist
Motivation
Android counterpart of the iOS
RemoteConfigSourceProvider(RevenueCat/purchases-ios#7093): the SDK needs an address book that tracks the healthy api/blob source and fails over when one is reported unhealthy.Description
WeightedSourceSelector.Note
Low Risk
New internal remote-config infrastructure with no changes to existing fetch paths in this PR; behavior is covered by unit and concurrency tests.
Overview
Adds
RemoteConfigSourceProvider, a thread-safe “address book” for remote config that tracks separate API and blob source lists and fails over independently when a source is reported unhealthy.Callers get the current handle via
getCurrent, advance withreportUnhealthy(only when the reported URL still matches the active source, so stale/concurrent reports cannot skip ahead), and reset a purpose withrestart. Sources are deduped by URL at build time (highest priority, weight tie-break) and ordered through the existingWeightedSourceSelector.Includes a broad
RemoteConfigSourceProviderTestsuite covering selection, dedup, API/blob isolation, stale-report races, restart, and concurrent reporting.Reviewed by Cursor Bugbot for commit 6e5556e. Bugbot is set up for automated code reviews on this repo. Configure here.