Просмотр исходного кода

Adds new parameter details for the connection failed event. (#697)

* Adds new parameter details for the connection failed event.

Adds suspend and shard_changed details.

* Updates the used strophejs version in dependencies.

* Updates the used strophejs version in dependencies (package-lock file).

* Changes to always report suspend time, reports 0 on no suspend detected.

* Updates the used strophejs version in dependencies (1.2.14-1).

* Changes details field name.
dev1
Дамян Минков 7 лет назад
Родитель
Сommit
4daf8e7e95
7 измененных файлов: 134 добавлений и 18 удалений
  1. 4
    2
      JitsiConnection.js
  2. 6
    1
      JitsiConnectionEvents.js
  3. 62
    0
      modules/xmpp/strophe.ping.js
  4. 47
    1
      modules/xmpp/xmpp.js
  5. 1
    3
      package-lock.json
  6. 1
    1
      package.json
  7. 13
    10
      service/statistics/AnalyticsEvents.js

+ 4
- 2
JitsiConnection.js Просмотреть файл

23
     this.options = options;
23
     this.options = options;
24
     this.xmpp = new XMPP(options, token);
24
     this.xmpp = new XMPP(options, token);
25
 
25
 
26
+    /* eslint-disable max-params */
26
     this.addEventListener(JitsiConnectionEvents.CONNECTION_FAILED,
27
     this.addEventListener(JitsiConnectionEvents.CONNECTION_FAILED,
27
-        (errType, msg) => {
28
+        (errType, msg, credentials, details) => {
28
             Statistics.sendAnalyticsAndLog(
29
             Statistics.sendAnalyticsAndLog(
29
-                createConnectionFailedEvent(errType, msg));
30
+                createConnectionFailedEvent(errType, msg, details));
30
         });
31
         });
32
+    /* eslint-enable max-params */
31
 
33
 
32
     this.addEventListener(JitsiConnectionEvents.CONNECTION_DISCONNECTED,
34
     this.addEventListener(JitsiConnectionEvents.CONNECTION_DISCONNECTED,
33
         msg => {
35
         msg => {

+ 6
- 1
JitsiConnectionEvents.js Просмотреть файл

24
  * Indicates that the connection has been failed for some reason. The event
24
  * Indicates that the connection has been failed for some reason. The event
25
  * provides the following parameters to its listeners:
25
  * provides the following parameters to its listeners:
26
  *
26
  *
27
- * @param err {string} the error (message) associated with the failure
27
+ * @param errType {JitsiConnectionErrors} the type of error associated with
28
+ * the failure
29
+ * @param errReason {string} the error (message) associated with the failure
30
+ * @param credentials {object} the credentials used to connect (if any)
31
+ * @param errReasonDetails {object} an optional object with details about
32
+ * the error, like shard moving, suspending. Used for analytics purposes.
28
  */
33
  */
29
 export const CONNECTION_FAILED = 'connection.connectionFailed';
34
 export const CONNECTION_FAILED = 'connection.connectionFailed';
30
 
35
 

+ 62
- 0
modules/xmpp/strophe.ping.js Просмотреть файл

23
  */
23
  */
24
 const PING_THRESHOLD = 3;
24
 const PING_THRESHOLD = 3;
25
 
25
 
26
+/**
27
+ * The number of timestamps of send pings to keep.
28
+ * The current value is 2 minutes.
29
+ * @type {number} number of timestamps.
30
+ */
31
+const PING_TIMESTAMPS_TO_KEEP = 120000 / PING_INTERVAL;
32
+
26
 /**
33
 /**
27
  * XEP-0199 ping plugin.
34
  * XEP-0199 ping plugin.
28
  *
35
  *
38
         super();
45
         super();
39
         this.failedPings = 0;
46
         this.failedPings = 0;
40
         this.xmpp = xmpp;
47
         this.xmpp = xmpp;
48
+        this.pingExecIntervals = new Array(PING_TIMESTAMPS_TO_KEEP);
41
     }
49
     }
42
 
50
 
43
     /**
51
     /**
60
      * timeout <tt>error<//t> callback is called with undefined error argument.
68
      * timeout <tt>error<//t> callback is called with undefined error argument.
61
      */
69
      */
62
     ping(jid, success, error, timeout) {
70
     ping(jid, success, error, timeout) {
71
+        this._addPingExecutionTimestamp();
72
+
63
         const iq = $iq({
73
         const iq = $iq({
64
             type: 'get',
74
             type: 'get',
65
             to: jid
75
             to: jid
141
             logger.info('Ping interval cleared');
151
             logger.info('Ping interval cleared');
142
         }
152
         }
143
     }
153
     }
154
+
155
+    /**
156
+     * Adds the current time to the array of send ping timestamps.
157
+     * @private
158
+     */
159
+    _addPingExecutionTimestamp() {
160
+        this.pingExecIntervals.push(new Date().getTime());
161
+
162
+        // keep array length to PING_TIMESTAMPS_TO_KEEP
163
+        if (this.pingExecIntervals.length > PING_TIMESTAMPS_TO_KEEP) {
164
+            this.pingExecIntervals.shift();
165
+        }
166
+    }
167
+
168
+    /**
169
+     * Returns the maximum time between the recent sent pings, if there is a
170
+     * big value it means the computer was inactive for some time(suspended).
171
+     * Checks the maximum gap between sending pings, considering and the
172
+     * current time. Trying to detect computer inactivity (sleep).
173
+     *
174
+     * @returns {int} the time ping was suspended, if it was not 0 is returned.
175
+     */
176
+    getPingSuspendTime() {
177
+        const pingIntervals = this.pingExecIntervals.slice();
178
+
179
+        // we need current time, as if ping was sent now
180
+        // if computer sleeps we will get correct interval after next
181
+        // scheduled ping, bet we sometimes need that interval before waiting
182
+        // for the next ping, on closing the connection on error.
183
+        pingIntervals.push(new Date().getTime());
184
+
185
+        let maxInterval = 0;
186
+        let previousTS = pingIntervals[0];
187
+
188
+        pingIntervals.forEach(e => {
189
+            const currentInterval = e - previousTS;
190
+
191
+            if (currentInterval > maxInterval) {
192
+                maxInterval = currentInterval;
193
+            }
194
+
195
+            previousTS = e;
196
+        });
197
+
198
+        // remove the interval between the ping sent
199
+        // this way in normal execution there is no suspend and the return
200
+        // will be 0 or close to 0.
201
+        maxInterval -= PING_INTERVAL;
202
+
203
+        // make sure we do not return less than 0
204
+        return Math.max(maxInterval, 0);
205
+    }
144
 }
206
 }
145
 
207
 
146
 /**
208
 /**

+ 47
- 1
modules/xmpp/xmpp.js Просмотреть файл

202
             } else if (this.connectionFailed) {
202
             } else if (this.connectionFailed) {
203
                 this.eventEmitter.emit(
203
                 this.eventEmitter.emit(
204
                     JitsiConnectionEvents.CONNECTION_FAILED,
204
                     JitsiConnectionEvents.CONNECTION_FAILED,
205
-                    JitsiConnectionErrors.OTHER_ERROR, errMsg);
205
+                    JitsiConnectionErrors.OTHER_ERROR,
206
+                    errMsg,
207
+                    undefined, /* credentials */
208
+                    this._getConnectionFailedReasonDetails());
206
             } else if (wasIntentionalDisconnect) {
209
             } else if (wasIntentionalDisconnect) {
207
                 this.eventEmitter.emit(
210
                 this.eventEmitter.emit(
208
                     JitsiConnectionEvents.CONNECTION_DISCONNECTED, errMsg);
211
                     JitsiConnectionEvents.CONNECTION_DISCONNECTED, errMsg);
509
         initRayo();
512
         initRayo();
510
         initStropheLogger();
513
         initStropheLogger();
511
     }
514
     }
515
+
516
+    /**
517
+     * Returns details about connection failure. Shard change or is it after
518
+     * suspend.
519
+     * @returns {object} contains details about a connection failure.
520
+     * @private
521
+     */
522
+    _getConnectionFailedReasonDetails() {
523
+        const details = {};
524
+
525
+        // check for moving between shard if information is available
526
+        if (this.options.deploymentInfo
527
+            && this.options.deploymentInfo.shard
528
+            && this.connection._proto
529
+            && this.connection._proto.lastResponseHeaders) {
530
+
531
+            // split headers by line
532
+            const headersArr = this.connection._proto.lastResponseHeaders
533
+                .trim().split(/[\r\n]+/);
534
+            const headers = {};
535
+
536
+            headersArr.forEach(line => {
537
+                const parts = line.split(': ');
538
+                const header = parts.shift();
539
+                const value = parts.join(': ');
540
+
541
+                headers[header] = value;
542
+            });
543
+
544
+            /* eslint-disable camelcase */
545
+            details.shard_changed
546
+                = this.options.deploymentInfo.shard
547
+                    !== headers['x-jitsi-shard'];
548
+            /* eslint-enable camelcase */
549
+        }
550
+
551
+        /* eslint-disable camelcase */
552
+        // check for possible suspend
553
+        details.suspend_time = this.connection.ping.getPingSuspendTime();
554
+        /* eslint-enable camelcase */
555
+
556
+        return details;
557
+    }
512
 }
558
 }

+ 1
- 3
package-lock.json Просмотреть файл

6327
       "dev": true
6327
       "dev": true
6328
     },
6328
     },
6329
     "strophe.js": {
6329
     "strophe.js": {
6330
-      "version": "1.2.14",
6331
-      "resolved": "https://registry.npmjs.org/strophe.js/-/strophe.js-1.2.14.tgz",
6332
-      "integrity": "sha1-fO7sUbMnLMXGxq53R0eApYQPGqc="
6330
+      "version": "github:jitsi/strophejs#d05254fb28f4bbe6df5f905358582db3a12ee04c"
6333
     },
6331
     },
6334
     "strophejs-plugin-disco": {
6332
     "strophejs-plugin-disco": {
6335
       "version": "0.0.2",
6333
       "version": "0.0.2",

+ 1
- 1
package.json Просмотреть файл

23
     "sdp-interop": "0.1.12",
23
     "sdp-interop": "0.1.12",
24
     "sdp-simulcast": "0.2.1",
24
     "sdp-simulcast": "0.2.1",
25
     "sdp-transform": "2.3.0",
25
     "sdp-transform": "2.3.0",
26
-    "strophe.js": "1.2.14",
26
+    "strophe.js": "github:jitsi/strophejs#1.2.14-1",
27
     "strophejs-plugin-disco": "0.0.2",
27
     "strophejs-plugin-disco": "0.0.2",
28
     "webrtc-adapter": "github:webrtc/adapter#1eec19782b4058d186341263e7d049cea3e3290a",
28
     "webrtc-adapter": "github:webrtc/adapter#1eec19782b4058d186341263e7d049cea3e3290a",
29
     "yaeti": "1.0.1"
29
     "yaeti": "1.0.1"

+ 13
- 10
service/statistics/AnalyticsEvents.js Просмотреть файл

226
  * Creates an event which indicates that the XMPP connection failed
226
  * Creates an event which indicates that the XMPP connection failed
227
  * @param errorType TODO
227
  * @param errorType TODO
228
  * @param errorMessage TODO
228
  * @param errorMessage TODO
229
- */
230
-export const createConnectionFailedEvent = function(errorType, errorMessage) {
231
-    return {
232
-        type: TYPE_OPERATIONAL,
233
-        action: 'connection.failed',
234
-        attributes: {
235
-            'error_type': errorType,
236
-            'error_message': errorMessage
237
-        }
229
+ * @param detail connection failed details.
230
+ */
231
+export const createConnectionFailedEvent
232
+    = function(errorType, errorMessage, details) {
233
+        return {
234
+            type: TYPE_OPERATIONAL,
235
+            action: 'connection.failed',
236
+            attributes: {
237
+                'error_type': errorType,
238
+                'error_message': errorMessage,
239
+                ...details
240
+            }
241
+        };
238
     };
242
     };
239
-};
240
 
243
 
241
 /**
244
 /**
242
  * Creates an operational event which indicates that a particular connection
245
  * Creates an operational event which indicates that a particular connection

Загрузка…
Отмена
Сохранить