소스 검색

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>() {