TODOs: Try to join with exponential backoff
Previously, we would only attempt to join a syncgroup twice. Now,
we'll do it up to 5 times (though we can change that default). These
tries are done with exponential backoff, so theoretically there is
no need for a limit.
The reason this wasn't included before is that it seemed to trigger
sync breakages; however, those problems have been resolved now that
syncgroup ad failures don't break sync anymore.
Change-Id: I7ba05a178c243718a24b5c2920a9a510be48fe25
diff --git a/app/src/syncbase/java/io/v/todos/persistence/syncbase/SyncbaseMain.java b/app/src/syncbase/java/io/v/todos/persistence/syncbase/SyncbaseMain.java
index 33bfa9e..04958b0 100644
--- a/app/src/syncbase/java/io/v/todos/persistence/syncbase/SyncbaseMain.java
+++ b/app/src/syncbase/java/io/v/todos/persistence/syncbase/SyncbaseMain.java
@@ -19,6 +19,7 @@
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;
@@ -54,6 +55,8 @@
private static final String
TAG = SyncbaseMain.class.getSimpleName();
+ private static int DEFAULT_MAX_JOIN_ATTEMPTS = 5;
+
private final IdGenerator mIdGenerator = new IdGenerator(IdAlphabets.COLLECTION_ID, true);
private final Map<String, MainListTracker> mTaskTrackers = new HashMap<>();
@@ -90,27 +93,7 @@
Log.d(TAG, "Found a list id from userdata watch: " + listId + " with owner: "
+ ownerBlessing);
- trap(Futures.catchingAsync(joinListSyncgroup(listId, ownerBlessing),
- SyncgroupJoinFailedException.class, new
- AsyncFunction<SyncgroupJoinFailedException, SyncgroupSpec>() {
- public ListenableFuture<SyncgroupSpec> apply(@Nullable
- SyncgroupJoinFailedException
- input) throws
- Exception {
- Log.d(TAG, "Join failed. Sleeping and trying again: " + listId);
- return sExecutor.schedule(new Callable<SyncgroupSpec>() {
-
- @Override
- public SyncgroupSpec call() throws Exception {
- Log.d(TAG, "Sleep done. Trying again: " + listId);
-
- // If this errors, then we will not get another chance to see
- // this syncgroup until the app is restarted.
- return joinListSyncgroup(listId, ownerBlessing).get();
- }
- }, RETRY_DELAY, TimeUnit.MILLISECONDS);
- }
- }));
+ trap(joinWithBackoff(listId, ownerBlessing));
MainListTracker listTracker = new MainListTracker(getVContext(), getDatabase(),
listId, listener);
@@ -170,6 +153,47 @@
CLOUD_NAME, CLOUD_BLESSING, memberInfo);
}
+ private ListenableFuture<SyncgroupSpec> joinWithBackoff(String listId, String ownerBlessing) {
+ return joinWithBackoff(listId, ownerBlessing, 0, DEFAULT_MAX_JOIN_ATTEMPTS);
+ }
+
+ private ListenableFuture<SyncgroupSpec> joinWithBackoff(final String listId, final String
+ ownerBlessing, final int numTimes, final int limit) {
+ final String debugString = (numTimes + 1) + "/" + limit + " for: " + listId;
+ Log.d(TAG, "Join attempt " + debugString);
+ if (numTimes + 1 == limit) { // final attempt!
+ return joinListSyncgroup(listId, ownerBlessing);
+ }
+ final long delay = RETRY_DELAY * (1 << numTimes);
+ return Futures.catchingAsync(
+ joinListSyncgroup(listId, ownerBlessing),
+ SyncgroupJoinFailedException.class,
+ new AsyncFunction<SyncgroupJoinFailedException, SyncgroupSpec>() {
+ public ListenableFuture<SyncgroupSpec> apply(@Nullable
+ SyncgroupJoinFailedException
+ input) {
+ Log.d(TAG, "Join failed. Sleeping " + debugString + " with delay " + delay);
+ return sExecutor.schedule(new Callable<SyncgroupSpec>() {
+
+
+ @Override
+ public SyncgroupSpec call() {
+ Log.d(TAG, "Sleep done. Retry " + debugString);
+
+ // If this errors, then we will not get another chance to
+ // see this syncgroup until the app is restarted.
+ try {
+ return joinWithBackoff(listId, ownerBlessing,
+ numTimes + 1, limit).get();
+ } catch (InterruptedException | ExecutionException e) {
+ return null;
+ }
+ }
+ }, delay, TimeUnit.MILLISECONDS);
+ }
+ });
+ }
+
private ListenableFuture<Void> createListSyncgroup(Id id) {
String listId = id.getName();
final String sgName = computeListSyncgroupName(listId);
diff --git a/app/src/syncbase/java/io/v/todos/persistence/syncbase/SyncbasePersistence.java b/app/src/syncbase/java/io/v/todos/persistence/syncbase/SyncbasePersistence.java
index 13365d4..87ae010 100644
--- a/app/src/syncbase/java/io/v/todos/persistence/syncbase/SyncbasePersistence.java
+++ b/app/src/syncbase/java/io/v/todos/persistence/syncbase/SyncbasePersistence.java
@@ -99,7 +99,7 @@
protected static final String LISTS_PREFIX = "lists_";
protected static final long
SHORT_TIMEOUT = 2500,
- RETRY_DELAY = 2000,
+ RETRY_DELAY = 300,
MEMBER_TIMER_DELAY = 100,
MEMBER_TIMER_PERIOD = 5000;
public static final String