@microsoft/1ds-post-js 3.1.10 → 3.1.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +123 -5
- package/bundle/{ms.post-3.1.10.gbl.js → ms.post-3.1.11.gbl.js} +163 -86
- package/bundle/ms.post-3.1.11.gbl.js.map +1 -0
- package/bundle/ms.post-3.1.11.gbl.min.js +7 -0
- package/bundle/ms.post-3.1.11.gbl.min.js.map +1 -0
- package/bundle/ms.post-3.1.11.integrity.json +46 -0
- package/bundle/{ms.post-3.1.10.js → ms.post-3.1.11.js} +163 -86
- package/bundle/ms.post-3.1.11.js.map +1 -0
- package/bundle/ms.post-3.1.11.min.js +7 -0
- package/bundle/ms.post-3.1.11.min.js.map +1 -0
- package/bundle/ms.post.gbl.js +162 -85
- package/bundle/ms.post.gbl.js.map +1 -1
- package/bundle/ms.post.gbl.min.js +2 -2
- package/bundle/ms.post.gbl.min.js.map +1 -1
- package/bundle/ms.post.integrity.json +17 -17
- package/bundle/ms.post.js +162 -85
- package/bundle/ms.post.js.map +1 -1
- package/bundle/ms.post.min.js +2 -2
- package/bundle/ms.post.min.js.map +1 -1
- package/dist/ms.post.js +101 -47
- package/dist/ms.post.js.map +1 -1
- package/dist/ms.post.min.js +2 -2
- package/dist/ms.post.min.js.map +1 -1
- package/dist-esm/src/BatchNotificationActions.js +1 -1
- package/dist-esm/src/ClockSkewManager.js +1 -1
- package/dist-esm/src/Constants.d.ts +1 -0
- package/dist-esm/src/Constants.js +2 -1
- package/dist-esm/src/Constants.js.map +1 -1
- package/dist-esm/src/DataModels.d.ts +49 -0
- package/dist-esm/src/DataModels.js +1 -1
- package/dist-esm/src/EventBatch.js +1 -1
- package/dist-esm/src/HttpManager.d.ts +1 -1
- package/dist-esm/src/HttpManager.js +63 -24
- package/dist-esm/src/HttpManager.js.map +1 -1
- package/dist-esm/src/Index.js +1 -1
- package/dist-esm/src/KillSwitch.js +1 -1
- package/dist-esm/src/PostChannel.js +51 -28
- package/dist-esm/src/PostChannel.js.map +1 -1
- package/dist-esm/src/RetryPolicy.js +1 -1
- package/dist-esm/src/Serializer.js +1 -1
- package/dist-esm/src/typings/XDomainRequest.js +1 -1
- package/package.json +2 -2
- package/src/Constants.ts +1 -0
- package/src/DataModels.ts +62 -1
- package/src/HttpManager.ts +67 -22
- package/src/PostChannel.ts +56 -28
- package/bundle/ms.post-3.1.10.gbl.js.map +0 -1
- package/bundle/ms.post-3.1.10.gbl.min.js +0 -7
- package/bundle/ms.post-3.1.10.gbl.min.js.map +0 -1
- package/bundle/ms.post-3.1.10.integrity.json +0 -46
- package/bundle/ms.post-3.1.10.js.map +0 -1
- package/bundle/ms.post-3.1.10.min.js +0 -7
- package/bundle/ms.post-3.1.10.min.js.map +0 -1
package/src/HttpManager.ts
CHANGED
|
@@ -27,10 +27,14 @@ import { XDomainRequest as IXDomainRequest } from "./typings/XDomainRequest";
|
|
|
27
27
|
import {
|
|
28
28
|
defaultCacheControl, defaultContentType, DisabledPropertyName, Method, strApiKey, strAuthXToken, strCacheControl,
|
|
29
29
|
strClientId, strClientVersion, strContentTypeHeader, strDropped, strKillDurationHeader, strKillDurationSecondsHeader,
|
|
30
|
-
strKillTokensHeader, strMsaDeviceTicket, strMsfpc, strOther, strRequeue, strResponseFail, strSending, strTimeDeltaHeader,
|
|
30
|
+
strKillTokensHeader, strMsaDeviceTicket, strMsfpc, strNoResponseBody, strOther, strRequeue, strResponseFail, strSending, strTimeDeltaHeader,
|
|
31
31
|
strTimeDeltaToApply, strUploadTime
|
|
32
32
|
} from "./Constants";
|
|
33
33
|
|
|
34
|
+
const strSendAttempt = "sendAttempt";
|
|
35
|
+
|
|
36
|
+
const _noResponseQs = "&" + strNoResponseBody + "=true";
|
|
37
|
+
|
|
34
38
|
// TypeScript removed this interface so we need to declare the global so we can check for it's existence.
|
|
35
39
|
declare var XDomainRequest: {
|
|
36
40
|
prototype: IXDomainRequest;
|
|
@@ -140,7 +144,7 @@ export class HttpManager {
|
|
|
140
144
|
* @constructor
|
|
141
145
|
* @param requestQueue - The queue that contains the requests to be sent.
|
|
142
146
|
*/
|
|
143
|
-
constructor(maxEventsPerBatch: number, maxConnections: number,
|
|
147
|
+
constructor(maxEventsPerBatch: number, maxConnections: number, maxRequestRetriesBeforeBackoff: number, actions: BatchNotificationActions) {
|
|
144
148
|
let _urlString: string = "?cors=true&" + strContentTypeHeader.toLowerCase() + "=" + defaultContentType;
|
|
145
149
|
let _killSwitch: EVTKillSwitch = new EVTKillSwitch();
|
|
146
150
|
let _paused = false;
|
|
@@ -159,6 +163,8 @@ export class HttpManager {
|
|
|
159
163
|
let _cookieMgr: ICookieMgr;
|
|
160
164
|
let _isUnloading = false;
|
|
161
165
|
let _useHeaders = false;
|
|
166
|
+
let _xhrTimeout: number;
|
|
167
|
+
let _disableXhrSync: boolean;
|
|
162
168
|
|
|
163
169
|
dynamicProto(HttpManager, this, (_self) => {
|
|
164
170
|
let _sendCredentials = true;
|
|
@@ -189,10 +195,15 @@ export class HttpManager {
|
|
|
189
195
|
enableCompoundKey = !!channelConfig.enableCompoundKey;
|
|
190
196
|
}
|
|
191
197
|
|
|
198
|
+
_xhrTimeout = channelConfig.xhrTimeout;
|
|
199
|
+
_disableXhrSync = channelConfig.disableXhrSync;
|
|
200
|
+
|
|
192
201
|
_useBeacons = !isReactNative(); // Only use beacons if not running in React Native
|
|
193
202
|
_serializer = new Serializer(_core, valueSanitizer, stringifyObjects, enableCompoundKey);
|
|
194
203
|
|
|
195
204
|
let syncHttpInterface = httpInterface;
|
|
205
|
+
let beaconHttpInterface: IXHROverride = channelConfig.alwaysUseXhrOverride ? httpInterface : null;
|
|
206
|
+
let fetchSyncHttpInterface: IXHROverride = channelConfig.alwaysUseXhrOverride ? httpInterface : null;
|
|
196
207
|
|
|
197
208
|
if (!httpInterface) {
|
|
198
209
|
_customHttpInterface = false;
|
|
@@ -232,8 +243,8 @@ export class HttpManager {
|
|
|
232
243
|
_sendInterfaces = {
|
|
233
244
|
[EventSendType.Batched]: httpInterface,
|
|
234
245
|
[EventSendType.Synchronous]: syncHttpInterface || _getSenderInterface([TransportType.Xhr, TransportType.Fetch, TransportType.Beacon], true),
|
|
235
|
-
[EventSendType.SendBeacon]: _getSenderInterface([TransportType.Beacon, TransportType.Fetch, TransportType.Xhr], true)
|
|
236
|
-
[EventSendType.SyncFetch]: _getSenderInterface([TransportType.Fetch, TransportType.Beacon, TransportType.Xhr], true)
|
|
246
|
+
[EventSendType.SendBeacon]: beaconHttpInterface || _getSenderInterface([TransportType.Beacon, TransportType.Fetch], true) || syncHttpInterface || _getSenderInterface([TransportType.Xhr], true),
|
|
247
|
+
[EventSendType.SyncFetch]: fetchSyncHttpInterface || _getSenderInterface([TransportType.Fetch, TransportType.Beacon], true) || syncHttpInterface || _getSenderInterface([TransportType.Xhr], true)
|
|
237
248
|
};
|
|
238
249
|
};
|
|
239
250
|
|
|
@@ -278,6 +289,9 @@ export class HttpManager {
|
|
|
278
289
|
// It doesn't support custom headers, so no action is taken with current requestHeaders
|
|
279
290
|
let xdr = new XDomainRequest();
|
|
280
291
|
xdr.open(Method, payload.urlString);
|
|
292
|
+
if (payload.timeout) {
|
|
293
|
+
xdr.timeout = payload.timeout;
|
|
294
|
+
}
|
|
281
295
|
|
|
282
296
|
// can't get the status code in xdr.
|
|
283
297
|
xdr.onload = () => {
|
|
@@ -310,6 +324,7 @@ export class HttpManager {
|
|
|
310
324
|
}
|
|
311
325
|
|
|
312
326
|
function _fetchSendPost(payload: IPayloadData, oncomplete: OnCompleteCallback, sync?: boolean) {
|
|
327
|
+
let theUrl = payload.urlString;
|
|
313
328
|
let ignoreResponse = false;
|
|
314
329
|
let responseHandled = false;
|
|
315
330
|
let requestInit: RequestInit = {
|
|
@@ -324,6 +339,7 @@ export class HttpManager {
|
|
|
324
339
|
// As a sync request (during unload), it is unlikely that we will get a chance to process the response so
|
|
325
340
|
// just like beacon send assume that the events have been accepted and processed
|
|
326
341
|
ignoreResponse = true;
|
|
342
|
+
theUrl += _noResponseQs;
|
|
327
343
|
}
|
|
328
344
|
}
|
|
329
345
|
|
|
@@ -337,7 +353,7 @@ export class HttpManager {
|
|
|
337
353
|
requestInit.headers = payload.headers;
|
|
338
354
|
}
|
|
339
355
|
|
|
340
|
-
fetch(
|
|
356
|
+
fetch(theUrl, requestInit).then((response) => {
|
|
341
357
|
let headerMap = {};
|
|
342
358
|
let responseText = "";
|
|
343
359
|
if (response.headers) {
|
|
@@ -370,9 +386,21 @@ export class HttpManager {
|
|
|
370
386
|
responseHandled = true;
|
|
371
387
|
_doOnComplete(oncomplete, 200, {});
|
|
372
388
|
}
|
|
389
|
+
|
|
390
|
+
if (!responseHandled && payload.timeout > 0) {
|
|
391
|
+
// Simulate timeout
|
|
392
|
+
_postManager._setTimeoutOverride(() => {
|
|
393
|
+
if (!responseHandled) {
|
|
394
|
+
// Assume a 500 response (which will cause a retry)
|
|
395
|
+
responseHandled = true;
|
|
396
|
+
_doOnComplete(oncomplete, 500, {});
|
|
397
|
+
}
|
|
398
|
+
}, payload.timeout);
|
|
399
|
+
}
|
|
373
400
|
}
|
|
374
401
|
|
|
375
402
|
function _xhrSendPost(payload: IPayloadData, oncomplete: OnCompleteCallback, sync?: boolean) {
|
|
403
|
+
let theUrl = payload.urlString;
|
|
376
404
|
|
|
377
405
|
function _appendHeader(theHeaders, xhr, name) {
|
|
378
406
|
if (!theHeaders[name] && xhr && xhr.getResponseHeader) {
|
|
@@ -405,25 +433,28 @@ export class HttpManager {
|
|
|
405
433
|
function xhrComplete(xhr, responseTxt?) {
|
|
406
434
|
_doOnComplete(oncomplete, xhr.status, _getAllResponseHeaders(xhr), responseTxt);
|
|
407
435
|
}
|
|
436
|
+
if (sync && payload.disableXhrSync) {
|
|
437
|
+
sync = false;
|
|
438
|
+
}
|
|
408
439
|
|
|
409
|
-
let
|
|
440
|
+
let xhrRequest = openXhr(Method, theUrl, _sendCredentials, true, sync, payload.timeout);
|
|
410
441
|
|
|
411
442
|
// Set custom headers (e.g. gzip) here (after open())
|
|
412
443
|
objForEachKey(payload.headers, (name, value) => {
|
|
413
|
-
|
|
444
|
+
xhrRequest.setRequestHeader(name, value);
|
|
414
445
|
});
|
|
415
|
-
|
|
416
|
-
let response = _getResponseText(
|
|
417
|
-
xhrComplete(
|
|
446
|
+
xhrRequest.onload = () => {
|
|
447
|
+
let response = _getResponseText(xhrRequest);
|
|
448
|
+
xhrComplete(xhrRequest, response);
|
|
418
449
|
_handleCollectorResponse(response);
|
|
419
450
|
};
|
|
420
|
-
|
|
421
|
-
xhrComplete(
|
|
451
|
+
xhrRequest.onerror = () => {
|
|
452
|
+
xhrComplete(xhrRequest);
|
|
422
453
|
};
|
|
423
|
-
|
|
424
|
-
xhrComplete(
|
|
454
|
+
xhrRequest.ontimeout = () => {
|
|
455
|
+
xhrComplete(xhrRequest);
|
|
425
456
|
};
|
|
426
|
-
|
|
457
|
+
xhrRequest.send(payload.data);
|
|
427
458
|
}
|
|
428
459
|
|
|
429
460
|
function _doOnComplete(oncomplete: OnCompleteCallback, status: number, headers: { [headerName: string]: string }, response?: string) {
|
|
@@ -440,9 +471,11 @@ export class HttpManager {
|
|
|
440
471
|
let internalPayloadData = payload as IInternalPayloadData;
|
|
441
472
|
let status = 200;
|
|
442
473
|
let thePayload = internalPayloadData._thePayload;
|
|
474
|
+
let theUrl = payload.urlString + _noResponseQs;
|
|
475
|
+
|
|
443
476
|
try {
|
|
444
477
|
let nav = getNavigator();
|
|
445
|
-
if (!nav.sendBeacon(
|
|
478
|
+
if (!nav.sendBeacon(theUrl, payload.data)) {
|
|
446
479
|
if (thePayload) {
|
|
447
480
|
// Failed to send entire payload so try and split data and try to send as much events as possible
|
|
448
481
|
let droppedBatches: EventBatch[] = [];
|
|
@@ -450,7 +483,7 @@ export class HttpManager {
|
|
|
450
483
|
if (droppedBatches && theBatch && theBatch.count() > 0) {
|
|
451
484
|
let theEvents = theBatch.events();
|
|
452
485
|
for (let lp = 0; lp < theEvents.length; lp++) {
|
|
453
|
-
if (!nav.sendBeacon(
|
|
486
|
+
if (!nav.sendBeacon(theUrl, _serializer.getEventBlob(theEvents[lp]))) {
|
|
454
487
|
// Can't send anymore, so split the batch and drop the rest
|
|
455
488
|
droppedBatches.push(theBatch.split(lp));
|
|
456
489
|
break;
|
|
@@ -809,7 +842,6 @@ export class HttpManager {
|
|
|
809
842
|
useHeaders = useHeaders || requestDetails.useHdrs;
|
|
810
843
|
|
|
811
844
|
let sendEventStart = getTime();
|
|
812
|
-
let strSendAttempt = "sendAttempt";
|
|
813
845
|
|
|
814
846
|
doPerf(_core, () => "HttpManager:_doPayloadSend", () => {
|
|
815
847
|
// Increment the send attempt count and add timings after packaging (So it's not serialized in the 1st attempt)
|
|
@@ -844,9 +876,14 @@ export class HttpManager {
|
|
|
844
876
|
urlString: requestDetails.url,
|
|
845
877
|
headers: requestDetails.hdrs,
|
|
846
878
|
_thePayload: thePayload,
|
|
847
|
-
_sendReason: sendReason
|
|
879
|
+
_sendReason: sendReason,
|
|
880
|
+
timeout: _xhrTimeout
|
|
848
881
|
};
|
|
849
882
|
|
|
883
|
+
if (!isUndefined(_disableXhrSync)) {
|
|
884
|
+
orgPayloadData.disableXhrSync = !!_disableXhrSync;
|
|
885
|
+
}
|
|
886
|
+
|
|
850
887
|
// Only automatically add the following headers if already sending headers and we are not attempting to avoid an options call
|
|
851
888
|
if (useHeaders) {
|
|
852
889
|
if (!_hasHeader(orgPayloadData.headers, strCacheControl)) {
|
|
@@ -902,7 +939,9 @@ export class HttpManager {
|
|
|
902
939
|
let hookData: IPayloadData = {
|
|
903
940
|
data: orgPayloadData.data,
|
|
904
941
|
urlString: orgPayloadData.urlString,
|
|
905
|
-
headers: extend({}, orgPayloadData.headers)
|
|
942
|
+
headers: extend({}, orgPayloadData.headers),
|
|
943
|
+
timeout: orgPayloadData.timeout,
|
|
944
|
+
disableXhrSync: orgPayloadData.disableXhrSync
|
|
906
945
|
};
|
|
907
946
|
|
|
908
947
|
let senderCalled = false;
|
|
@@ -988,7 +1027,7 @@ export class HttpManager {
|
|
|
988
1027
|
|
|
989
1028
|
// Disabling triple-equals rule to avoid httpOverrides from failing because they are returning a string value
|
|
990
1029
|
// tslint:disable-next-line:triple-equals
|
|
991
|
-
if (status == 200) {
|
|
1030
|
+
if (status == 200 || status == 204) {
|
|
992
1031
|
// Response was successfully sent
|
|
993
1032
|
reason = EventBatchNotificationReason.Complete;
|
|
994
1033
|
return;
|
|
@@ -1008,7 +1047,8 @@ export class HttpManager {
|
|
|
1008
1047
|
reason = EventBatchNotificationReason.RequeueEvents;
|
|
1009
1048
|
let retryCount = thePayload.retryCnt;
|
|
1010
1049
|
if (thePayload.sendType === EventSendType.Batched) {
|
|
1011
|
-
|
|
1050
|
+
// attempt to resend the entire batch
|
|
1051
|
+
if (retryCount < maxRequestRetriesBeforeBackoff) {
|
|
1012
1052
|
isRetrying = true;
|
|
1013
1053
|
_doAction(() => {
|
|
1014
1054
|
// try to resend the same batches
|
|
@@ -1023,6 +1063,11 @@ export class HttpManager {
|
|
|
1023
1063
|
}, _isUnloading, RetryPolicy.getMillisToBackoffForRetry(retryCount));
|
|
1024
1064
|
} else {
|
|
1025
1065
|
backOffTrans = true;
|
|
1066
|
+
if (_isUnloading) {
|
|
1067
|
+
// we are unloading so don't try and requeue the events otherwise let the events get requeued and resent during the backoff sending
|
|
1068
|
+
// This will also cause the events to be purged based on the priority (if necessary)
|
|
1069
|
+
reason = EventBatchNotificationReason.NonRetryableStatus;
|
|
1070
|
+
}
|
|
1026
1071
|
}
|
|
1027
1072
|
}
|
|
1028
1073
|
}
|
package/src/PostChannel.ts
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
EventLatency, NotificationManager, EventsDiscardedReason, IPlugin, ITelemetryItem,
|
|
9
9
|
IAppInsightsCore, isValueAssigned, addPageUnloadEventListener, addPageHideEventListener, addPageShowEventListener, setProcessTelemetryTimings,
|
|
10
10
|
isWindowObjectAvailable, IProcessTelemetryContext, SendRequestReason, arrForEach,
|
|
11
|
-
LoggingSeverity, _ExtendedInternalMessageId, doPerf, objForEachKey, optimizeObject, isChromium, getWindow, EventSendType, addEventHandler, getDocument,
|
|
11
|
+
LoggingSeverity, _ExtendedInternalMessageId, doPerf, objForEachKey, optimizeObject, isChromium, getWindow, EventSendType, addEventHandler, getDocument, isBeaconsSupported, isReactNative, isFetchSupported, isNumber,
|
|
12
12
|
} from "@microsoft/1ds-core-js";
|
|
13
13
|
import {
|
|
14
14
|
IChannelConfiguration, RT_PROFILE, NRT_PROFILE, IPostChannel,
|
|
@@ -25,14 +25,18 @@ const FlushCheckTimer = 0.250; // This needs to be in seconds, so this
|
|
|
25
25
|
const MaxNumberEventPerBatch = 500;
|
|
26
26
|
const EventsDroppedAtOneTime = 20;
|
|
27
27
|
const MaxSendAttempts = 6;
|
|
28
|
+
const MaxSyncUnloadSendAttempts = 2; // Assuming 2 based on beforeunload and unload
|
|
28
29
|
const MaxBackoffCount = 4;
|
|
29
30
|
const globalContext = isWindowObjectAvailable ? window : this;
|
|
30
31
|
const MaxConnections = 2;
|
|
31
|
-
const
|
|
32
|
+
const MaxRequestRetriesBeforeBackoff = 1;
|
|
32
33
|
|
|
33
34
|
const strEventsDiscarded = "eventsDiscarded";
|
|
34
35
|
const strOverrideInstrumentationKey = "overrideInstrumentationKey";
|
|
35
36
|
|
|
37
|
+
const strMaxEventRetryAttempts = "maxEventRetryAttempts";
|
|
38
|
+
const strMaxUnloadEventRetryAttempts = "maxUnloadEventRetryAttempts";
|
|
39
|
+
|
|
36
40
|
interface IPostChannelBatchQueue {
|
|
37
41
|
/**
|
|
38
42
|
* This is the actual queue of event batches
|
|
@@ -86,13 +90,16 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
86
90
|
let _delayedBatchReason: SendRequestReason;
|
|
87
91
|
let _optimizeObject: boolean = true;
|
|
88
92
|
let _isPageUnloadTriggered = false;
|
|
93
|
+
let _disableXhrSync = false;
|
|
94
|
+
let _maxEventSendAttempts: number = MaxSendAttempts;
|
|
95
|
+
let _maxUnloadEventSendAttempts: number = MaxSyncUnloadSendAttempts;
|
|
89
96
|
|
|
90
97
|
dynamicProto(PostChannel, this, (_self, _base) => {
|
|
91
98
|
_initializeProfiles();
|
|
92
99
|
_clearQueues();
|
|
93
100
|
_setAutoLimits();
|
|
94
101
|
|
|
95
|
-
_httpManager = new HttpManager(MaxNumberEventPerBatch, MaxConnections,
|
|
102
|
+
_httpManager = new HttpManager(MaxNumberEventPerBatch, MaxConnections, MaxRequestRetriesBeforeBackoff, {
|
|
96
103
|
requeue: _requeueEvents,
|
|
97
104
|
send: _sendingEvent,
|
|
98
105
|
sent: _eventsSentEvent,
|
|
@@ -120,14 +127,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
120
127
|
// Only try and use the optimizeObject() if this appears to be a chromium based browser and it has not been explicitly disabled
|
|
121
128
|
_optimizeObject = !_config.disableOptimizeObj && isChromium();
|
|
122
129
|
|
|
123
|
-
|
|
124
|
-
extendedCore.getWParam = () => {
|
|
125
|
-
var wparam = 0;
|
|
126
|
-
if (_config.ignoreMc1Ms0CookieProcessing) {
|
|
127
|
-
wparam = wparam | 2;
|
|
128
|
-
}
|
|
129
|
-
return wparam | existingGetWParamMethod();
|
|
130
|
-
};
|
|
130
|
+
_hookWParam(extendedCore);
|
|
131
131
|
|
|
132
132
|
if (_config.eventsLimitInMem > 0) {
|
|
133
133
|
_queueSizeLimit = _config.eventsLimitInMem;
|
|
@@ -141,6 +141,15 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
141
141
|
_autoFlushEventsLimit = _config.autoFlushEventsLimit;
|
|
142
142
|
}
|
|
143
143
|
|
|
144
|
+
_disableXhrSync = _config.disableXhrSync;
|
|
145
|
+
if (isNumber(_config[strMaxEventRetryAttempts])) {
|
|
146
|
+
_maxEventSendAttempts = _config[strMaxEventRetryAttempts];
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (isNumber(_config[strMaxUnloadEventRetryAttempts])) {
|
|
150
|
+
_maxUnloadEventSendAttempts = _config[strMaxUnloadEventRetryAttempts];
|
|
151
|
+
}
|
|
152
|
+
|
|
144
153
|
_setAutoLimits();
|
|
145
154
|
|
|
146
155
|
if (_config.httpXHROverride && _config.httpXHROverride.sendPOST) {
|
|
@@ -157,27 +166,12 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
157
166
|
_self._notificationManager = coreConfig.extensionConfig.NotificationManager;
|
|
158
167
|
_httpManager.initialize(endpointUrl, _self.core as IExtendedAppInsightsCore, _self, _xhrOverride, _config);
|
|
159
168
|
|
|
160
|
-
function _handleUnloadEvents(evt: any) {
|
|
161
|
-
let theEvt = evt || getWindow().event; // IE 8 does not pass the event
|
|
162
|
-
if (theEvt.type !== "beforeunload") {
|
|
163
|
-
// Only set the unload trigger if not beforeunload event as beforeunload can be cancelled while the other events can't
|
|
164
|
-
_isPageUnloadTriggered = true;
|
|
165
|
-
_httpManager.setUnloading(_isPageUnloadTriggered);
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
_releaseAllQueues(EventSendType.SendBeacon, SendRequestReason.Unload);
|
|
169
|
-
}
|
|
170
|
-
|
|
171
169
|
let excludePageUnloadEvents = coreConfig.disablePageUnloadEvents || [];
|
|
172
170
|
|
|
173
171
|
// When running in Web browsers try to send all telemetry if page is unloaded
|
|
174
172
|
addPageUnloadEventListener(_handleUnloadEvents, excludePageUnloadEvents);
|
|
175
173
|
addPageHideEventListener(_handleUnloadEvents, excludePageUnloadEvents);
|
|
176
|
-
addPageShowEventListener(
|
|
177
|
-
// Handle the page becoming visible again
|
|
178
|
-
_isPageUnloadTriggered = false;
|
|
179
|
-
_httpManager.setUnloading(_isPageUnloadTriggered);
|
|
180
|
-
}, coreConfig.disablePageShowEvents);
|
|
174
|
+
addPageShowEventListener(_handleShowEvents, coreConfig.disablePageShowEvents);
|
|
181
175
|
|
|
182
176
|
_self.setInitialized(true);
|
|
183
177
|
}, () => ({ coreConfig, core, extensions }));
|
|
@@ -222,6 +216,35 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
222
216
|
_self.processNext(event, itemCtx);
|
|
223
217
|
};
|
|
224
218
|
|
|
219
|
+
function _hookWParam(extendedCore: IExtendedAppInsightsCore) {
|
|
220
|
+
var existingGetWParamMethod = extendedCore.getWParam;
|
|
221
|
+
extendedCore.getWParam = () => {
|
|
222
|
+
var wparam = 0;
|
|
223
|
+
if (_config.ignoreMc1Ms0CookieProcessing) {
|
|
224
|
+
wparam = wparam | 2;
|
|
225
|
+
}
|
|
226
|
+
return wparam | existingGetWParamMethod();
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// Moving event handlers out from the initialize closure so that any local variables can be garbage collected
|
|
231
|
+
function _handleUnloadEvents(evt: any) {
|
|
232
|
+
let theEvt = evt || getWindow().event; // IE 8 does not pass the event
|
|
233
|
+
if (theEvt.type !== "beforeunload") {
|
|
234
|
+
// Only set the unload trigger if not beforeunload event as beforeunload can be cancelled while the other events can't
|
|
235
|
+
_isPageUnloadTriggered = true;
|
|
236
|
+
_httpManager.setUnloading(_isPageUnloadTriggered);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
_releaseAllQueues(EventSendType.SendBeacon, SendRequestReason.Unload);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
function _handleShowEvents(evt: any) {
|
|
243
|
+
// Handle the page becoming visible again
|
|
244
|
+
_isPageUnloadTriggered = false;
|
|
245
|
+
_httpManager.setUnloading(_isPageUnloadTriggered);
|
|
246
|
+
}
|
|
247
|
+
|
|
225
248
|
function _addEventToQueues(event: IPostTransmissionTelemetryItem, append: boolean) {
|
|
226
249
|
// If send attempt field is undefined we should set it to 0.
|
|
227
250
|
if (!event.sendAttempt) {
|
|
@@ -805,6 +828,11 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
805
828
|
*/
|
|
806
829
|
function _requeueEvents(batches: EventBatch[], reason?: number) {
|
|
807
830
|
let droppedEvents: IPostTransmissionTelemetryItem[] = [];
|
|
831
|
+
let maxSendAttempts = _maxEventSendAttempts;
|
|
832
|
+
if (_isPageUnloadTriggered) {
|
|
833
|
+
// If a page unlaod has been triggered reduce the number of times we try to "retry"
|
|
834
|
+
maxSendAttempts = _maxUnloadEventSendAttempts;
|
|
835
|
+
}
|
|
808
836
|
|
|
809
837
|
arrForEach(batches, (theBatch) => {
|
|
810
838
|
if (theBatch && theBatch.count() > 0) {
|
|
@@ -817,7 +845,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
817
845
|
theEvent.sync = false;
|
|
818
846
|
}
|
|
819
847
|
|
|
820
|
-
if (theEvent.sendAttempt <
|
|
848
|
+
if (theEvent.sendAttempt < maxSendAttempts) {
|
|
821
849
|
// Reset the event timings
|
|
822
850
|
setProcessTelemetryTimings(theEvent, _self.identifier);
|
|
823
851
|
_addEventToQueues(theEvent, false);
|