diff --git a/client/CHANGES.txt b/client/CHANGES.txt
index e7505e9af..34ca99376 100644
--- a/client/CHANGES.txt
+++ b/client/CHANGES.txt
@@ -1,5 +1,8 @@
CHANGES
+4.1.5 (Apr 6, 2021)
+-Updated: Streaming retry fix.
+
4.1.4 (Mar 19, 2021)
- Updated: Internal cache structure refactor.
- Updated: Streaming revamp with several bugfixes and improved log messages.
diff --git a/client/pom.xml b/client/pom.xml
index e5b2d16e1..ce5a16e1e 100644
--- a/client/pom.xml
+++ b/client/pom.xml
@@ -5,7 +5,7 @@
io.split.client
java-client-parent
- 4.1.4
+ 4.1.5
java-client
jar
diff --git a/client/src/main/java/io/split/engine/common/SynchronizerImp.java b/client/src/main/java/io/split/engine/common/SynchronizerImp.java
index 4e8115b18..0d22ff9f2 100644
--- a/client/src/main/java/io/split/engine/common/SynchronizerImp.java
+++ b/client/src/main/java/io/split/engine/common/SynchronizerImp.java
@@ -19,6 +19,7 @@
public class SynchronizerImp implements Synchronizer {
private static final Logger _log = LoggerFactory.getLogger(Synchronizer.class);
+ private static final int RETRIES_NUMBER = 10;
private final SplitSynchronizationTask _splitSynchronizationTask;
private final SplitFetcher _splitFetcher;
@@ -69,8 +70,10 @@ public void stopPeriodicFetching() {
@Override
public void refreshSplits(long targetChangeNumber) {
- if (targetChangeNumber > _splitCache.getChangeNumber()) {
+ int retries = 1;
+ while(targetChangeNumber > _splitCache.getChangeNumber() && retries <= RETRIES_NUMBER) {
_splitFetcher.forceRefresh(true);
+ retries++;
}
}
@@ -84,7 +87,8 @@ public void localKillSplit(String splitName, String defaultTreatment, long newCh
@Override
public void refreshSegment(String segmentName, long changeNumber) {
- if (changeNumber > _segmentCache.getChangeNumber(segmentName)) {
+ int retries = 1;
+ while(changeNumber > _segmentCache.getChangeNumber(segmentName) && retries <= RETRIES_NUMBER) {
SegmentFetcher fetcher = _segmentSynchronizationTaskImp.getFetcher(segmentName);
try{
fetcher.fetch(true);
@@ -93,6 +97,7 @@ public void refreshSegment(String segmentName, long changeNumber) {
catch (NullPointerException np){
throw new NullPointerException();
}
+ retries++;
}
}
}
diff --git a/client/src/test/java/io/split/engine/common/SynchronizerTest.java b/client/src/test/java/io/split/engine/common/SynchronizerTest.java
index f4e0bec31..5bff9d000 100644
--- a/client/src/test/java/io/split/engine/common/SynchronizerTest.java
+++ b/client/src/test/java/io/split/engine/common/SynchronizerTest.java
@@ -4,6 +4,7 @@
import io.split.cache.SplitCache;
import io.split.engine.experiments.SplitFetcherImp;
import io.split.engine.experiments.SplitSynchronizationTask;
+import io.split.engine.segments.SegmentFetcher;
import io.split.engine.segments.SegmentSynchronizationTask;
import org.junit.Before;
import org.junit.Test;
@@ -15,6 +16,7 @@ public class SynchronizerTest {
private SplitFetcherImp _splitFetcher;
private SplitCache _splitCache;
private Synchronizer _synchronizer;
+ private SegmentCache _segmentCache;
@Before
public void beforeMethod() {
@@ -22,7 +24,7 @@ public void beforeMethod() {
_segmentFetcher = Mockito.mock(SegmentSynchronizationTask.class);
_splitFetcher = Mockito.mock(SplitFetcherImp.class);
_splitCache = Mockito.mock(SplitCache.class);
- SegmentCache _segmentCache = Mockito.mock(SegmentCache.class);
+ _segmentCache = Mockito.mock(SegmentCache.class);
_synchronizer = new SynchronizerImp(_refreshableSplitFetcherTask, _splitFetcher, _segmentFetcher, _splitCache, _segmentCache);
}
@@ -51,4 +53,23 @@ public void stopPeriodicFetching() {
Mockito.verify(_refreshableSplitFetcherTask, Mockito.times(1)).stop();
Mockito.verify(_segmentFetcher, Mockito.times(1)).stop();
}
+
+ @Test
+ public void streamingRetryOnSplit() {
+ Mockito.when(_splitCache.getChangeNumber()).thenReturn(0l).thenReturn(0l).thenReturn(1l);
+ _synchronizer.refreshSplits(1l);
+
+ Mockito.verify(_splitCache, Mockito.times(3)).getChangeNumber();
+ }
+
+ @Test
+ public void streamingRetryOnSegment() {
+ SegmentFetcher fetcher = Mockito.mock(SegmentFetcher.class);
+ Mockito.when(_segmentFetcher.getFetcher(Mockito.anyString())).thenReturn(fetcher);
+ Mockito.when(_segmentCache.getChangeNumber(Mockito.anyString())).thenReturn(0l).thenReturn(0l).thenReturn(1l);
+ _synchronizer.refreshSegment("Segment",1l);
+
+ Mockito.verify(_segmentCache, Mockito.times(3)).getChangeNumber(Mockito.anyString());
+ }
+
}
diff --git a/pom.xml b/pom.xml
index 4ed8474e4..a0384c7cf 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
4.0.0
io.split.client
java-client-parent
- 4.1.4
+ 4.1.5
diff --git a/testing/pom.xml b/testing/pom.xml
index f13acaafe..97f24a133 100644
--- a/testing/pom.xml
+++ b/testing/pom.xml
@@ -6,7 +6,7 @@
io.split.client
java-client-parent
- 4.1.4
+ 4.1.5
java-client-testing