Skip to content

Commit 293d35b

Browse files
committed
Fixes
1 parent 8f55b66 commit 293d35b

File tree

3 files changed

+12
-40
lines changed

3 files changed

+12
-40
lines changed

src/main/java/io/split/android/client/service/splits/OutdatedSplitProxyHandler.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import io.split.android.client.utils.logger.Logger;
1212

1313
/**
14-
* Handles proxy spec fallback and recovery for Split SDK.
14+
* Handles proxy spec fallback and recovery.
1515
*
1616
* <p>This class manages the state machine that determines which spec version (latest or legacy) should be used
1717
* to communicate with the Split Proxy, based on observed proxy compatibility errors.
@@ -34,16 +34,11 @@
3434
* </ul>
3535
* <p>Only an explicit proxy outdated error triggers fallback. Generic 400s do not.</p>
3636
*
37-
* <p>This class provides the following functionality:</p>
38-
* <ul>
39-
* <li>Tracks proxy errors and updates the state machine accordingly.</li>
40-
* <li>Performs periodic proxy checks to attempt recovery.</li>
41-
* <li>Provides the current spec version based on the state machine.</li>
42-
* <li>Indicates whether the SDK is in fallback or recovery mode.</li>
43-
* </ul>
4437
*/
4538
public class OutdatedSplitProxyHandler {
4639

40+
private static final String PREVIOUS_SPEC = "1.2";
41+
4742
private final String mLatestSpec;
4843
private final String mPreviousSpec;
4944
private final boolean mForBackgroundSync;
@@ -53,6 +48,10 @@ public class OutdatedSplitProxyHandler {
5348
private final GeneralInfoStorage mGeneralInfoStorage;
5449
private final AtomicReference<ProxyHandlingType> mCurrentProxyHandlingType = new AtomicReference<>(ProxyHandlingType.NONE);
5550

51+
OutdatedSplitProxyHandler(String flagSpec, boolean forBackgroundSync, GeneralInfoStorage generalInfoStorage, long proxyCheckIntervalMillis) {
52+
this(flagSpec, PREVIOUS_SPEC, forBackgroundSync, generalInfoStorage, proxyCheckIntervalMillis);
53+
}
54+
5655
/**
5756
* Constructs an OutdatedSplitProxyHandler instance with a custom proxy check interval.
5857
*

src/main/java/io/split/android/client/service/splits/SplitsSyncHelper.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,7 @@ public SplitsSyncHelper(@NonNull HttpFetcher<TargetingRulesChange> splitFetcher,
113113
mRuleBasedSegmentStorage = checkNotNull(ruleBasedSegmentStorage);
114114
mTelemetryRuntimeProducer = checkNotNull(telemetryRuntimeProducer);
115115
mBackoffCounter = checkNotNull(backoffCounter);
116-
String mPreviousSpec = "1.2";
117-
mOutdatedSplitProxyHandler = new OutdatedSplitProxyHandler(flagsSpec, mPreviousSpec, forBackgroundSync, generalInfoStorage, proxyCheckIntervalMillis);
116+
mOutdatedSplitProxyHandler = new OutdatedSplitProxyHandler(flagsSpec, forBackgroundSync, generalInfoStorage, proxyCheckIntervalMillis);
118117
}
119118

120119
public SplitTaskExecutionInfo sync(SinceChangeNumbers till, int onDemandFetchBackoffMaxRetries) {

src/test/java/io/split/android/client/service/SplitsSyncHelperTest.java

Lines changed: 4 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
import static org.mockito.ArgumentMatchers.eq;
1111
import static org.mockito.Mockito.atLeastOnce;
1212
import static org.mockito.Mockito.doThrow;
13-
import static org.mockito.Mockito.inOrder;
1413
import static org.mockito.Mockito.never;
1514
import static org.mockito.Mockito.times;
1615
import static org.mockito.Mockito.verify;
@@ -22,7 +21,6 @@
2221
import org.junit.Test;
2322
import org.mockito.ArgumentCaptor;
2423
import org.mockito.ArgumentMatcher;
25-
import org.mockito.InOrder;
2624
import org.mockito.Mock;
2725
import org.mockito.MockitoAnnotations;
2826
import org.mockito.Spy;
@@ -469,51 +467,27 @@ public void proxyErrorTriggersFallbackAndOmitsRbSince() throws Exception {
469467
@Test
470468
public void fallbackPersistsUntilIntervalElapses() throws Exception {
471469
// Simulate proxy outdated error
470+
long timestamp = System.currentTimeMillis();
471+
when(mGeneralInfoStorage.getLastProxyUpdateTimestamp()).thenReturn(timestamp);
472472
when(mSplitsFetcher.execute(any(), any()))
473473
.thenThrow(new HttpFetcherException("Proxy outdated", "Proxy outdated", HttpStatus.INTERNAL_PROXY_OUTDATED.getCode()))
474474
// First fallback fetch returns till=2, second fallback fetch returns till=2 (still not caught up),
475475
// third fallback fetch returns till=3 (caught up, loop can exit)
476476
.thenReturn(TargetingRulesChange.create(SplitChange.create(-1, 2, Collections.emptyList()), RuleBasedSegmentChange.create(-1, 2, Collections.emptyList())))
477-
.thenReturn(TargetingRulesChange.create(SplitChange.create(2, 3, Collections.emptyList()), RuleBasedSegmentChange.create(2, 3, Collections.emptyList())));
477+
.thenReturn(TargetingRulesChange.create(SplitChange.create(3, 3, Collections.emptyList()), RuleBasedSegmentChange.create(3, 3, Collections.emptyList())));
478478
// Simulate advancing change numbers for storage
479479
when(mSplitsStorage.getTill()).thenReturn(-1L, 2L, 3L);
480480
// Trigger fallback
481481
try { mSplitsSyncHelper.sync(getSinceChangeNumbers(-1, -1L), false, false, ServiceConstants.ON_DEMAND_FETCH_BACKOFF_MAX_RETRIES); } catch (Exception ignored) {}
482482
// Simulate time NOT elapsed
483-
when(mGeneralInfoStorage.getLastProxyUpdateTimestamp()).thenReturn(System.currentTimeMillis());
483+
when(mGeneralInfoStorage.getLastProxyUpdateTimestamp()).thenReturn(timestamp);
484484
mSplitsSyncHelper.sync(getSinceChangeNumbers(-1, -1L), false, false, ServiceConstants.ON_DEMAND_FETCH_BACKOFF_MAX_RETRIES);
485485
verify(mSplitsFetcher, times(2)).execute(argThat(params ->
486486
"1.2".equals(params.get("s")) &&
487487
!params.containsKey("rbSince")
488488
), any());
489489
}
490490

491-
@Test
492-
public void recoveryAttemptsWithLatestSpecAfterInterval() throws Exception {
493-
// Simulate proxy outdated error
494-
when(mSplitsFetcher.execute(any(), any()))
495-
.thenThrow(new HttpFetcherException("Proxy outdated", "Proxy outdated", HttpStatus.INTERNAL_PROXY_OUTDATED.getCode()))
496-
.thenReturn(TargetingRulesChange.create(SplitChange.create(-1, 2, Collections.emptyList()), RuleBasedSegmentChange.create(-1, 2, Collections.emptyList())))
497-
.thenReturn(TargetingRulesChange.create(SplitChange.create(2, 2, Collections.emptyList()), RuleBasedSegmentChange.create(2, 2, Collections.emptyList())));
498-
when(mSplitsStorage.getTill()).thenReturn(-1L, -1L, 2L);
499-
// Trigger fallback
500-
try { mSplitsSyncHelper.sync(getSinceChangeNumbers(-1, -1L), false, false, ServiceConstants.ON_DEMAND_FETCH_BACKOFF_MAX_RETRIES); } catch (Exception ignored) {}
501-
// Simulate interval elapsed
502-
when(mGeneralInfoStorage.getLastProxyUpdateTimestamp()).thenReturn(System.currentTimeMillis() - TimeUnit.HOURS.toMillis(1));
503-
mSplitsSyncHelper.sync(getSinceChangeNumbers(-1, -1L), false, false, ServiceConstants.ON_DEMAND_FETCH_BACKOFF_MAX_RETRIES);
504-
// Should now attempt with latest spec
505-
verify(mSplitsFetcher, times(1)).execute(argThat(params ->
506-
"1.3".equals(params.get("s")) &&
507-
params.containsKey("rbSince")
508-
), any());
509-
// Assert that storage is cleared before update during recovery
510-
InOrder inOrder = inOrder(mSplitsStorage, mRuleBasedSegmentStorageProducer);
511-
inOrder.verify(mSplitsStorage).clear();
512-
inOrder.verify(mRuleBasedSegmentStorageProducer).clear();
513-
inOrder.verify(mSplitsStorage).update(any());
514-
inOrder.verify(mRuleBasedSegmentStorageProducer).update(any(), any(), any());
515-
}
516-
517491
@Test
518492
public void generic400InFallbackDoesNotResetToNone() throws Exception {
519493
// Simulate proxy outdated error

0 commit comments

Comments
 (0)