瀏覽代碼

Add exponential backoff when trying to pull signaling messages again

When pulling signaling messages failed the source observable was
immediately subscribed again, which immediately triggered another pull.
Rather than hammering the server or a flaky network with new requests
again and again now further requests are performed with an incremental
delay (up to 16 seconds).

The delay is increased only when several requests fail in a row, and it
is reset as soon as a request succeeds.

Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
Daniel Calviño Sánchez 2 年之前
父節點
當前提交
4b4b9da2b1
共有 1 個文件被更改,包括 11 次插入1 次删除
  1. 11 1
      app/src/main/java/com/nextcloud/talk/activities/CallActivity.java

+ 11 - 1
app/src/main/java/com/nextcloud/talk/activities/CallActivity.java

@@ -138,6 +138,7 @@ import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
 
 import javax.inject.Inject;
 
@@ -1472,6 +1473,8 @@ public class CallActivity extends CallBaseActivity {
                             int apiVersion = ApiUtils.getSignalingApiVersion(conversationUser,
                                                                              new int[]{ApiUtils.APIv3, 2, 1});
 
+                            AtomicInteger delayOnError = new AtomicInteger(0);
+
                             ncApi.pullSignalingMessages(credentials,
                                                         ApiUtils.getUrlForSignaling(apiVersion,
                                                                                     baseUrl,
@@ -1480,13 +1483,20 @@ public class CallActivity extends CallBaseActivity {
                                 .observeOn(AndroidSchedulers.mainThread())
                                 .repeatWhen(observable -> observable)
                                 .takeWhile(observable -> isConnectionEstablished())
+                                .doOnNext(value -> delayOnError.set(0))
                                 .retryWhen(errors -> errors
                                     .flatMap(error -> {
                                         if (!isConnectionEstablished()) {
                                             return Observable.error(error);
                                         }
 
-                                        return Observable.just(0l);
+                                        if (delayOnError.get() == 0) {
+                                            delayOnError.set(1);
+                                        } else if (delayOnError.get() < 16) {
+                                            delayOnError.set(delayOnError.get() * 2);
+                                        }
+
+                                        return Observable.timer(delayOnError.get(), TimeUnit.SECONDS);
                                     })
                                 )
                                 .subscribe(new Observer<SignalingOverall>() {