瀏覽代碼

feat(XmppConnection): use full jitter backoff patter for resume retry

dev1
paweldomas 5 年之前
父節點
當前提交
8a41d02407
共有 2 個檔案被更改,包括 35 行新增2 行删除
  1. 14
    0
      modules/util/Retry.js
  2. 21
    2
      modules/xmpp/XmppConnection.js

+ 14
- 0
modules/util/Retry.js 查看文件

1
+/**
2
+* Gets next timeout using the full jitter pattern.
3
+*
4
+* NOTE that there are no checks for argument correctness, so either do the math or use defaults.
5
+*
6
+* @param {number} retry - The retry number.
7
+* @param {number} minDelay - The minimal delay in milliseconds.
8
+* @param {number} base - The exponent base.
9
+* @returns {number} - The amount of waiting before trying another time given in milliseconds.
10
+* @private
11
+*/
12
+export function getJitterDelay(retry, minDelay = 500, base = 2) {
13
+    return Math.floor((Math.random() * ((Math.pow(base, retry) * 1000) - minDelay)) + minDelay);
14
+}

+ 21
- 2
modules/xmpp/XmppConnection.js 查看文件

3
 import 'strophejs-plugin-stream-management';
3
 import 'strophejs-plugin-stream-management';
4
 
4
 
5
 import Listenable from '../util/Listenable';
5
 import Listenable from '../util/Listenable';
6
+import { getJitterDelay } from '../util/Retry';
6
 
7
 
7
 import LastSuccessTracker from './StropheBoshLastSuccess';
8
 import LastSuccessTracker from './StropheBoshLastSuccess';
8
 
9
 
50
             enableWebsocketResume: typeof enableWebsocketResume === 'undefined' ? true : enableWebsocketResume,
51
             enableWebsocketResume: typeof enableWebsocketResume === 'undefined' ? true : enableWebsocketResume,
51
             websocketKeepAlive: typeof websocketKeepAlive === 'undefined' ? 4 * 60 * 1000 : Number(websocketKeepAlive)
52
             websocketKeepAlive: typeof websocketKeepAlive === 'undefined' ? 4 * 60 * 1000 : Number(websocketKeepAlive)
52
         };
53
         };
54
+
55
+        /**
56
+         * The counter increased before each resume retry attempt, used to calculate exponential backoff.
57
+         * @type {number}
58
+         * @private
59
+         */
60
+        this._resumeRetryN = 0;
53
         this._stropheConn = new Strophe.Connection(serviceUrl);
61
         this._stropheConn = new Strophe.Connection(serviceUrl);
54
         this._usesWebsocket = serviceUrl.startsWith('ws:') || serviceUrl.startsWith('wss:');
62
         this._usesWebsocket = serviceUrl.startsWith('ws:') || serviceUrl.startsWith('wss:');
55
 
63
 
206
             if (status === Strophe.Status.CONNECTED) {
214
             if (status === Strophe.Status.CONNECTED) {
207
                 this._maybeEnableStreamResume();
215
                 this._maybeEnableStreamResume();
208
                 this._maybeStartWSKeepAlive();
216
                 this._maybeStartWSKeepAlive();
217
+                this._resumeRetryN = 0;
209
             } else if (status === Strophe.Status.DISCONNECTED) {
218
             } else if (status === Strophe.Status.DISCONNECTED) {
210
                 // FIXME add RECONNECTING state instead of blocking the DISCONNECTED update
219
                 // FIXME add RECONNECTING state instead of blocking the DISCONNECTED update
211
                 blockCallback = this._tryResumingConnection();
220
                 blockCallback = this._tryResumingConnection();
421
 
430
 
422
         if (resumeToken) {
431
         if (resumeToken) {
423
             clearTimeout(this._resumeTimeout);
432
             clearTimeout(this._resumeTimeout);
433
+
434
+            // FIXME detect internet offline
435
+            // The retry delay will be:
436
+            //   1st retry: 1.5s - 3s
437
+            //   2nd retry: 3s - 9s
438
+            //   3rd retry: 3s - 27s
439
+            this._resumeRetryN = Math.min(3, this._resumeRetryN + 1);
440
+            const retryTimeout = getJitterDelay(this._resumeRetryN, 1500, 3);
441
+
442
+            logger.info(`Will try to resume the XMPP connection in ${retryTimeout}ms`);
443
+
424
             this._resumeTimeout = setTimeout(() => {
444
             this._resumeTimeout = setTimeout(() => {
425
                 logger.info('Trying to resume the XMPP connection');
445
                 logger.info('Trying to resume the XMPP connection');
426
 
446
 
428
 
448
 
429
                 url.searchParams.set('previd', resumeToken);
449
                 url.searchParams.set('previd', resumeToken);
430
 
450
 
431
-                // FIXME remove XmppConnection 'service' setter
432
                 this._stropheConn.service = url.toString();
451
                 this._stropheConn.service = url.toString();
433
 
452
 
434
                 streamManagement.resume();
453
                 streamManagement.resume();
435
-            }, 3000 /* FIXME calculate delay with jitter */);
454
+            }, retryTimeout);
436
 
455
 
437
             return true;
456
             return true;
438
         }
457
         }

Loading…
取消
儲存