@microsoft/1ds-post-js 3.1.11 → 3.2.2
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 +2 -2
- package/bundle/{ms.post-3.1.11.gbl.js → ms.post-3.2.2.gbl.js} +1278 -548
- package/bundle/ms.post-3.2.2.gbl.js.map +1 -0
- package/bundle/ms.post-3.2.2.gbl.min.js +7 -0
- package/bundle/ms.post-3.2.2.gbl.min.js.map +1 -0
- package/bundle/ms.post-3.2.2.integrity.json +46 -0
- package/bundle/{ms.post-3.1.11.js → ms.post-3.2.2.js} +1278 -548
- package/bundle/ms.post-3.2.2.js.map +1 -0
- package/bundle/ms.post-3.2.2.min.js +7 -0
- package/bundle/ms.post-3.2.2.min.js.map +1 -0
- package/bundle/ms.post.gbl.js +1277 -547
- 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 +1277 -547
- 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 +212 -128
- 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.js +1 -1
- package/dist-esm/src/DataModels.js +1 -1
- package/dist-esm/src/EventBatch.js +1 -1
- package/dist-esm/src/HttpManager.d.ts +2 -1
- package/dist-esm/src/HttpManager.js +45 -40
- 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.d.ts +2 -9
- package/dist-esm/src/PostChannel.js +151 -97
- package/dist-esm/src/PostChannel.js.map +1 -1
- package/dist-esm/src/RetryPolicy.d.ts +20 -25
- package/dist-esm/src/RetryPolicy.js +35 -44
- package/dist-esm/src/RetryPolicy.js.map +1 -1
- package/dist-esm/src/Serializer.js +1 -1
- package/dist-esm/src/TimeoutOverrideWrapper.d.ts +18 -0
- package/dist-esm/src/TimeoutOverrideWrapper.js +28 -0
- package/dist-esm/src/TimeoutOverrideWrapper.js.map +1 -0
- package/dist-esm/src/typings/XDomainRequest.js +1 -1
- package/package.json +3 -3
- package/src/HttpManager.ts +48 -51
- package/src/PostChannel.ts +186 -119
- package/src/RetryPolicy.ts +33 -38
- package/src/TimeoutOverrideWrapper.ts +29 -0
- package/bundle/ms.post-3.1.11.gbl.js.map +0 -1
- package/bundle/ms.post-3.1.11.gbl.min.js +0 -7
- package/bundle/ms.post-3.1.11.gbl.min.js.map +0 -1
- package/bundle/ms.post-3.1.11.integrity.json +0 -46
- package/bundle/ms.post-3.1.11.js.map +0 -1
- package/bundle/ms.post-3.1.11.min.js +0 -7
- package/bundle/ms.post-3.1.11.min.js.map +0 -1
package/src/PostChannel.ts
CHANGED
|
@@ -3,12 +3,17 @@
|
|
|
3
3
|
* @author Abhilash Panwar (abpanwar); Hector Hernandez (hectorh); Nev Wylie (newylie)
|
|
4
4
|
* @copyright Microsoft 2018-2020
|
|
5
5
|
*/
|
|
6
|
+
import dynamicProto from "@microsoft/dynamicproto-js";
|
|
6
7
|
import {
|
|
7
8
|
BaseTelemetryPlugin, IChannelControls, IExtendedConfiguration, IExtendedAppInsightsCore,
|
|
8
|
-
|
|
9
|
-
IAppInsightsCore, isValueAssigned,
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
EventLatencyValue, NotificationManager, EventsDiscardedReason, IPlugin, ITelemetryItem,
|
|
10
|
+
IAppInsightsCore, isValueAssigned, setProcessTelemetryTimings,
|
|
11
|
+
IProcessTelemetryContext, SendRequestReason, arrForEach, eLoggingSeverity, _eExtendedInternalMessageId,
|
|
12
|
+
doPerf, objForEachKey, optimizeObject, isChromium, getWindow, EventSendType, isNumber, mergeEvtNamespace,
|
|
13
|
+
createUniqueNamespace, IProcessTelemetryUnloadContext, ITelemetryUnloadState,
|
|
14
|
+
addPageUnloadEventListener, addPageHideEventListener, addPageShowEventListener,
|
|
15
|
+
removePageUnloadEventListener, removePageHideEventListener, removePageShowEventListener,
|
|
16
|
+
_throwInternal, _eInternalMessageId, objDefineAccessors
|
|
12
17
|
} from "@microsoft/1ds-core-js";
|
|
13
18
|
import {
|
|
14
19
|
IChannelConfiguration, RT_PROFILE, NRT_PROFILE, IPostChannel,
|
|
@@ -17,9 +22,9 @@ import {
|
|
|
17
22
|
} from "./DataModels";
|
|
18
23
|
import { EventBatch } from "./EventBatch";
|
|
19
24
|
import { HttpManager } from "./HttpManager";
|
|
20
|
-
import
|
|
21
|
-
import dynamicProto from "@microsoft/dynamicproto-js";
|
|
25
|
+
import { retryPolicyGetMillisToBackoffForRetry } from "./RetryPolicy";
|
|
22
26
|
import { strMsaDeviceTicket } from "./Constants";
|
|
27
|
+
import { createTimeoutWrapper, ITimeoutOverrideWrapper, TimeoutClearFunc, TimeoutSetFunc } from "./TimeoutOverrideWrapper";
|
|
23
28
|
|
|
24
29
|
const FlushCheckTimer = 0.250; // This needs to be in seconds, so this is 250ms
|
|
25
30
|
const MaxNumberEventPerBatch = 500;
|
|
@@ -27,7 +32,6 @@ const EventsDroppedAtOneTime = 20;
|
|
|
27
32
|
const MaxSendAttempts = 6;
|
|
28
33
|
const MaxSyncUnloadSendAttempts = 2; // Assuming 2 based on beforeunload and unload
|
|
29
34
|
const MaxBackoffCount = 4;
|
|
30
|
-
const globalContext = isWindowObjectAvailable ? window : this;
|
|
31
35
|
const MaxConnections = 2;
|
|
32
36
|
const MaxRequestRetriesBeforeBackoff = 1;
|
|
33
37
|
|
|
@@ -37,6 +41,8 @@ const strOverrideInstrumentationKey = "overrideInstrumentationKey";
|
|
|
37
41
|
const strMaxEventRetryAttempts = "maxEventRetryAttempts";
|
|
38
42
|
const strMaxUnloadEventRetryAttempts = "maxUnloadEventRetryAttempts";
|
|
39
43
|
|
|
44
|
+
const strAddUnloadCb = "addUnloadCb";
|
|
45
|
+
|
|
40
46
|
interface IPostChannelBatchQueue {
|
|
41
47
|
/**
|
|
42
48
|
* This is the actual queue of event batches
|
|
@@ -59,7 +65,11 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
59
65
|
public priority = 1011;
|
|
60
66
|
public version = "#version#";
|
|
61
67
|
public _notificationManager: NotificationManager | undefined;
|
|
68
|
+
|
|
69
|
+
/** @deprecated This property is not intended to be used directly please let us know if you have taken a dependency on this property as it may be removed in a future release */
|
|
62
70
|
public _setTimeoutOverride: typeof setTimeout;
|
|
71
|
+
|
|
72
|
+
/** @deprecated This property is not intended to be used directly please let us know if you have taken a dependency on this property as it may be removed in a future release */
|
|
63
73
|
public _clearTimeoutOverride: typeof clearTimeout;
|
|
64
74
|
|
|
65
75
|
constructor() {
|
|
@@ -93,20 +103,11 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
93
103
|
let _disableXhrSync = false;
|
|
94
104
|
let _maxEventSendAttempts: number = MaxSendAttempts;
|
|
95
105
|
let _maxUnloadEventSendAttempts: number = MaxSyncUnloadSendAttempts;
|
|
106
|
+
let _evtNamespace: string | string[];
|
|
107
|
+
let _timeoutWrapper: ITimeoutOverrideWrapper;
|
|
96
108
|
|
|
97
109
|
dynamicProto(PostChannel, this, (_self, _base) => {
|
|
98
|
-
|
|
99
|
-
_clearQueues();
|
|
100
|
-
_setAutoLimits();
|
|
101
|
-
|
|
102
|
-
_httpManager = new HttpManager(MaxNumberEventPerBatch, MaxConnections, MaxRequestRetriesBeforeBackoff, {
|
|
103
|
-
requeue: _requeueEvents,
|
|
104
|
-
send: _sendingEvent,
|
|
105
|
-
sent: _eventsSentEvent,
|
|
106
|
-
drop: _eventsDropped,
|
|
107
|
-
rspFail: _eventsResponseFail,
|
|
108
|
-
oth: _otherEvent
|
|
109
|
-
});
|
|
110
|
+
_initDefaults();
|
|
110
111
|
|
|
111
112
|
// Special internal method to allow the DebugPlugin to hook embedded objects
|
|
112
113
|
_self["_getDbgPlgTargets"] = () => {
|
|
@@ -117,63 +118,68 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
117
118
|
doPerf(core, () => "PostChannel:initialize", () => {
|
|
118
119
|
let extendedCore = core as IExtendedAppInsightsCore;
|
|
119
120
|
_base.initialize(coreConfig, core, extensions);
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
121
|
+
try {
|
|
122
|
+
let hasAddUnloadCb = !!core[strAddUnloadCb];
|
|
123
|
+
_evtNamespace = mergeEvtNamespace(createUniqueNamespace(_self.identifier), core.evtNamespace && core.evtNamespace());
|
|
124
|
+
|
|
125
|
+
let ctx = _self._getTelCtx();
|
|
126
|
+
coreConfig.extensionConfig[_self.identifier] = coreConfig.extensionConfig[_self.identifier] || {};
|
|
127
|
+
_config = ctx.getExtCfg(_self.identifier);
|
|
128
|
+
_timeoutWrapper = createTimeoutWrapper(_config.setTimeoutOverride, _config.clearTimeoutOverride);
|
|
129
|
+
|
|
130
|
+
// Only try and use the optimizeObject() if this appears to be a chromium based browser and it has not been explicitly disabled
|
|
131
|
+
_optimizeObject = !_config.disableOptimizeObj && isChromium();
|
|
132
|
+
|
|
133
|
+
_hookWParam(extendedCore);
|
|
134
|
+
|
|
135
|
+
if (_config.eventsLimitInMem > 0) {
|
|
136
|
+
_queueSizeLimit = _config.eventsLimitInMem;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (_config.immediateEventLimit > 0) {
|
|
140
|
+
_immediateQueueSizeLimit = _config.immediateEventLimit;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (_config.autoFlushEventsLimit > 0) {
|
|
144
|
+
_autoFlushEventsLimit = _config.autoFlushEventsLimit;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
_disableXhrSync = _config.disableXhrSync;
|
|
148
|
+
if (isNumber(_config[strMaxEventRetryAttempts])) {
|
|
149
|
+
_maxEventSendAttempts = _config[strMaxEventRetryAttempts];
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (isNumber(_config[strMaxUnloadEventRetryAttempts])) {
|
|
153
|
+
_maxUnloadEventSendAttempts = _config[strMaxUnloadEventRetryAttempts];
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
_setAutoLimits();
|
|
157
|
+
|
|
158
|
+
if (_config.httpXHROverride && _config.httpXHROverride.sendPOST) {
|
|
159
|
+
_xhrOverride = _config.httpXHROverride;
|
|
160
|
+
}
|
|
161
|
+
if (isValueAssigned(coreConfig.anonCookieName)) {
|
|
162
|
+
_httpManager.addQueryStringParameter("anoncknm", coreConfig.anonCookieName);
|
|
163
|
+
}
|
|
164
|
+
_httpManager.sendHook = _config.payloadPreprocessor;
|
|
165
|
+
_httpManager.sendListener = _config.payloadListener;
|
|
166
|
+
|
|
167
|
+
// Override endpointUrl if provided in Post config
|
|
168
|
+
let endpointUrl = _config.overrideEndpointUrl ? _config.overrideEndpointUrl : coreConfig.endpointUrl;
|
|
169
|
+
_self._notificationManager = coreConfig.extensionConfig.NotificationManager;
|
|
170
|
+
_httpManager.initialize(endpointUrl, _self.core as IExtendedAppInsightsCore, _self, _xhrOverride, _config);
|
|
171
|
+
|
|
172
|
+
let excludePageUnloadEvents = coreConfig.disablePageUnloadEvents || [];
|
|
173
|
+
|
|
174
|
+
// When running in Web browsers try to send all telemetry if page is unloaded
|
|
175
|
+
addPageUnloadEventListener(_handleUnloadEvents, excludePageUnloadEvents, _evtNamespace);
|
|
176
|
+
addPageHideEventListener(_handleUnloadEvents, excludePageUnloadEvents, _evtNamespace);
|
|
177
|
+
addPageShowEventListener(_handleShowEvents, coreConfig.disablePageShowEvents, _evtNamespace);
|
|
178
|
+
} catch (e) {
|
|
179
|
+
// resetting the initialized state because of failure
|
|
180
|
+
_self.setInitialized(false);
|
|
181
|
+
throw e;
|
|
160
182
|
}
|
|
161
|
-
_httpManager.sendHook = _config.payloadPreprocessor;
|
|
162
|
-
_httpManager.sendListener = _config.payloadListener;
|
|
163
|
-
|
|
164
|
-
// Override endpointUrl if provided in Post config
|
|
165
|
-
let endpointUrl = _config.overrideEndpointUrl ? _config.overrideEndpointUrl : coreConfig.endpointUrl;
|
|
166
|
-
_self._notificationManager = coreConfig.extensionConfig.NotificationManager;
|
|
167
|
-
_httpManager.initialize(endpointUrl, _self.core as IExtendedAppInsightsCore, _self, _xhrOverride, _config);
|
|
168
|
-
|
|
169
|
-
let excludePageUnloadEvents = coreConfig.disablePageUnloadEvents || [];
|
|
170
|
-
|
|
171
|
-
// When running in Web browsers try to send all telemetry if page is unloaded
|
|
172
|
-
addPageUnloadEventListener(_handleUnloadEvents, excludePageUnloadEvents);
|
|
173
|
-
addPageHideEventListener(_handleUnloadEvents, excludePageUnloadEvents);
|
|
174
|
-
addPageShowEventListener(_handleShowEvents, coreConfig.disablePageShowEvents);
|
|
175
|
-
|
|
176
|
-
_self.setInitialized(true);
|
|
177
183
|
}, () => ({ coreConfig, core, extensions }));
|
|
178
184
|
};
|
|
179
185
|
|
|
@@ -216,6 +222,19 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
216
222
|
_self.processNext(event, itemCtx);
|
|
217
223
|
};
|
|
218
224
|
|
|
225
|
+
_self._doTeardown = (unloadCtx?: IProcessTelemetryUnloadContext, unloadState?: ITelemetryUnloadState) => {
|
|
226
|
+
_releaseAllQueues(EventSendType.SendBeacon, SendRequestReason.Unload);
|
|
227
|
+
_isTeardownCalled = true;
|
|
228
|
+
_httpManager.teardown();
|
|
229
|
+
|
|
230
|
+
removePageUnloadEventListener(null, _evtNamespace);
|
|
231
|
+
removePageHideEventListener(null, _evtNamespace);
|
|
232
|
+
removePageShowEventListener(null, _evtNamespace);
|
|
233
|
+
|
|
234
|
+
// Just register to remove all events associated with this namespace
|
|
235
|
+
_initDefaults();
|
|
236
|
+
};
|
|
237
|
+
|
|
219
238
|
function _hookWParam(extendedCore: IExtendedAppInsightsCore) {
|
|
220
239
|
var existingGetWParamMethod = extendedCore.getWParam;
|
|
221
240
|
extendedCore.getWParam = () => {
|
|
@@ -252,7 +271,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
252
271
|
}
|
|
253
272
|
// Add default latency
|
|
254
273
|
if (!event.latency) {
|
|
255
|
-
event.latency =
|
|
274
|
+
event.latency = EventLatencyValue.Normal;
|
|
256
275
|
}
|
|
257
276
|
|
|
258
277
|
// Remove extra AI properties if present
|
|
@@ -278,7 +297,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
278
297
|
// If the transmission is backed off then do not send synchronous events.
|
|
279
298
|
// We will convert these events to Real time latency instead.
|
|
280
299
|
if (_currentBackoffCount || _paused) {
|
|
281
|
-
event.latency =
|
|
300
|
+
event.latency = EventLatencyValue.RealTime;
|
|
282
301
|
event.sync = false;
|
|
283
302
|
} else {
|
|
284
303
|
// Log the event synchronously
|
|
@@ -300,7 +319,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
300
319
|
let evtLatency = event.latency;
|
|
301
320
|
let queueSize = _queueSize;
|
|
302
321
|
let queueLimit = _queueSizeLimit;
|
|
303
|
-
if (evtLatency ===
|
|
322
|
+
if (evtLatency === EventLatencyValue.Immediate) {
|
|
304
323
|
queueSize = _immediateQueueSize;
|
|
305
324
|
queueLimit = _immediateQueueSizeLimit;
|
|
306
325
|
}
|
|
@@ -310,11 +329,11 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
310
329
|
if (queueSize < queueLimit) {
|
|
311
330
|
eventDropped = !_addEventToProperQueue(event, append);
|
|
312
331
|
} else {
|
|
313
|
-
let dropLatency =
|
|
332
|
+
let dropLatency = EventLatencyValue.Normal;
|
|
314
333
|
let dropNumber = EventsDroppedAtOneTime;
|
|
315
|
-
if (evtLatency ===
|
|
334
|
+
if (evtLatency === EventLatencyValue.Immediate) {
|
|
316
335
|
// Only drop other immediate events as they are not technically sharing the general queue
|
|
317
|
-
dropLatency =
|
|
336
|
+
dropLatency = EventLatencyValue.Immediate;
|
|
318
337
|
dropNumber = 1;
|
|
319
338
|
}
|
|
320
339
|
|
|
@@ -341,7 +360,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
341
360
|
|
|
342
361
|
if (!doFlush && _autoFlushBatchLimit > 0) {
|
|
343
362
|
// Check the auto flush max batch size
|
|
344
|
-
for (let latency =
|
|
363
|
+
for (let latency = EventLatencyValue.Normal; !doFlush && latency <= EventLatencyValue.RealTime; latency++) {
|
|
345
364
|
let batchQueue: IPostChannelBatchQueue = _batchQueues[latency];
|
|
346
365
|
if (batchQueue && batchQueue.batches) {
|
|
347
366
|
arrForEach(batchQueue.batches, (theBatch) => {
|
|
@@ -357,12 +376,6 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
357
376
|
_performAutoFlush(true, doFlush);
|
|
358
377
|
};
|
|
359
378
|
|
|
360
|
-
_self.teardown = () => {
|
|
361
|
-
_releaseAllQueues(EventSendType.SendBeacon, SendRequestReason.Unload);
|
|
362
|
-
_isTeardownCalled = true;
|
|
363
|
-
_httpManager.teardown();
|
|
364
|
-
};
|
|
365
|
-
|
|
366
379
|
_self.pause = () => {
|
|
367
380
|
_clearScheduledTimer();
|
|
368
381
|
_paused = true;
|
|
@@ -418,7 +431,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
418
431
|
|
|
419
432
|
if (async) {
|
|
420
433
|
// Move all queued events to the HttpManager
|
|
421
|
-
_queueBatches(
|
|
434
|
+
_queueBatches(EventLatencyValue.Normal, EventSendType.Batched, sendReason);
|
|
422
435
|
|
|
423
436
|
// All events (should) have been queue -- lets just make sure the queue counts are correct to avoid queue exhaustion (previous bug #9685112)
|
|
424
437
|
_resetQueueCounts();
|
|
@@ -434,7 +447,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
434
447
|
}
|
|
435
448
|
} else {
|
|
436
449
|
// Now cause all queued events to be sent synchronously
|
|
437
|
-
_sendEventsForLatencyAndAbove(
|
|
450
|
+
_sendEventsForLatencyAndAbove(EventLatencyValue.Normal, EventSendType.Synchronous, sendReason);
|
|
438
451
|
|
|
439
452
|
if (callback !== null && callback !== undefined) {
|
|
440
453
|
callback();
|
|
@@ -494,7 +507,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
494
507
|
_immediateTimerId = _createTimer(() => {
|
|
495
508
|
_immediateTimerId = null;
|
|
496
509
|
// Only try to send direct events
|
|
497
|
-
_sendEventsForLatencyAndAbove(
|
|
510
|
+
_sendEventsForLatencyAndAbove(EventLatencyValue.Immediate, EventSendType.Batched, SendRequestReason.NormalSchedule);
|
|
498
511
|
_scheduleTimer();
|
|
499
512
|
}, immediateTimeOut);
|
|
500
513
|
}
|
|
@@ -506,7 +519,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
506
519
|
if (_hasEvents()) {
|
|
507
520
|
_scheduledTimerId = _createTimer(() => {
|
|
508
521
|
_scheduledTimerId = null;
|
|
509
|
-
_sendEventsForLatencyAndAbove(_timerCount === 0 ?
|
|
522
|
+
_sendEventsForLatencyAndAbove(_timerCount === 0 ? EventLatencyValue.RealTime : EventLatencyValue.Normal, EventSendType.Batched, SendRequestReason.NormalSchedule);
|
|
510
523
|
|
|
511
524
|
// Increment the count for next cycle
|
|
512
525
|
_timerCount++;
|
|
@@ -536,6 +549,51 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
536
549
|
}
|
|
537
550
|
};
|
|
538
551
|
|
|
552
|
+
function _initDefaults() {
|
|
553
|
+
_config = null;
|
|
554
|
+
_isTeardownCalled = false;
|
|
555
|
+
_flushCallbackQueue = [];
|
|
556
|
+
_flushCallbackTimerId = null;
|
|
557
|
+
_paused = false;
|
|
558
|
+
_immediateQueueSize = 0;
|
|
559
|
+
_immediateQueueSizeLimit = 500;
|
|
560
|
+
_queueSize = 0;
|
|
561
|
+
_queueSizeLimit = 10000;
|
|
562
|
+
_profiles = {};
|
|
563
|
+
_currentProfile = RT_PROFILE;
|
|
564
|
+
_scheduledTimerId = null;
|
|
565
|
+
_immediateTimerId = null;
|
|
566
|
+
_currentBackoffCount = 0;
|
|
567
|
+
_timerCount = 0;
|
|
568
|
+
_xhrOverride = null;
|
|
569
|
+
_batchQueues = {};
|
|
570
|
+
_autoFlushEventsLimit = undefined;
|
|
571
|
+
|
|
572
|
+
// either MaxBatchSize * (1+ Max Connections) or _queueLimit / 6 (where 3 latency Queues [normal, realtime, cost deferred] * 2 [allow half full -- allow for retry])
|
|
573
|
+
_autoFlushBatchLimit = 0;
|
|
574
|
+
_delayedBatchSendLatency = -1;
|
|
575
|
+
_delayedBatchReason = null;
|
|
576
|
+
_optimizeObject = true;
|
|
577
|
+
_isPageUnloadTriggered = false;
|
|
578
|
+
_disableXhrSync = false;
|
|
579
|
+
_maxEventSendAttempts = MaxSendAttempts;
|
|
580
|
+
_maxUnloadEventSendAttempts = MaxSyncUnloadSendAttempts;
|
|
581
|
+
_evtNamespace = null;
|
|
582
|
+
_timeoutWrapper = createTimeoutWrapper();
|
|
583
|
+
_httpManager = new HttpManager(MaxNumberEventPerBatch, MaxConnections, MaxRequestRetriesBeforeBackoff, {
|
|
584
|
+
requeue: _requeueEvents,
|
|
585
|
+
send: _sendingEvent,
|
|
586
|
+
sent: _eventsSentEvent,
|
|
587
|
+
drop: _eventsDropped,
|
|
588
|
+
rspFail: _eventsResponseFail,
|
|
589
|
+
oth: _otherEvent
|
|
590
|
+
}, _timeoutWrapper);
|
|
591
|
+
|
|
592
|
+
_initializeProfiles();
|
|
593
|
+
_clearQueues();
|
|
594
|
+
_setAutoLimits();
|
|
595
|
+
}
|
|
596
|
+
|
|
539
597
|
function _createTimer(theTimerFunc: () => void, timeOut: number): any {
|
|
540
598
|
// If the transmission is backed off make the timer at least 1 sec to allow for back off.
|
|
541
599
|
if (timeOut === 0 && _currentBackoffCount) {
|
|
@@ -544,14 +602,14 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
544
602
|
|
|
545
603
|
let timerMultiplier = 1000;
|
|
546
604
|
if (_currentBackoffCount) {
|
|
547
|
-
timerMultiplier =
|
|
605
|
+
timerMultiplier = retryPolicyGetMillisToBackoffForRetry(_currentBackoffCount - 1);
|
|
548
606
|
}
|
|
549
607
|
|
|
550
|
-
return
|
|
608
|
+
return _timeoutWrapper.set(theTimerFunc, timeOut * timerMultiplier);
|
|
551
609
|
}
|
|
552
610
|
function _clearScheduledTimer() {
|
|
553
611
|
if (_scheduledTimerId !== null) {
|
|
554
|
-
|
|
612
|
+
_timeoutWrapper.clear(_scheduledTimerId);
|
|
555
613
|
_scheduledTimerId = null;
|
|
556
614
|
_timerCount = 0;
|
|
557
615
|
}
|
|
@@ -563,13 +621,13 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
563
621
|
|
|
564
622
|
// Cancel all flush callbacks
|
|
565
623
|
if (_flushCallbackTimerId) {
|
|
566
|
-
|
|
624
|
+
_timeoutWrapper.clear(_flushCallbackTimerId);
|
|
567
625
|
_flushCallbackTimerId = null;
|
|
568
626
|
}
|
|
569
627
|
|
|
570
628
|
if (!_paused) {
|
|
571
629
|
// Queue all the remaining requests to be sent. The requests will be sent using HTML5 Beacons if they are available.
|
|
572
|
-
_sendEventsForLatencyAndAbove(
|
|
630
|
+
_sendEventsForLatencyAndAbove(EventLatencyValue.Normal, sendType, sendReason);
|
|
573
631
|
}
|
|
574
632
|
}
|
|
575
633
|
|
|
@@ -579,19 +637,19 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
579
637
|
* after flush are stored separately till we flush the current events.
|
|
580
638
|
*/
|
|
581
639
|
function _clearQueues() {
|
|
582
|
-
_batchQueues[
|
|
640
|
+
_batchQueues[EventLatencyValue.Immediate] = {
|
|
583
641
|
batches: [],
|
|
584
642
|
iKeyMap: {}
|
|
585
643
|
};
|
|
586
|
-
_batchQueues[
|
|
644
|
+
_batchQueues[EventLatencyValue.RealTime] = {
|
|
587
645
|
batches: [],
|
|
588
646
|
iKeyMap: {}
|
|
589
647
|
};
|
|
590
|
-
_batchQueues[
|
|
648
|
+
_batchQueues[EventLatencyValue.CostDeferred] = {
|
|
591
649
|
batches: [],
|
|
592
650
|
iKeyMap: {}
|
|
593
651
|
};
|
|
594
|
-
_batchQueues[
|
|
652
|
+
_batchQueues[EventLatencyValue.Normal] = {
|
|
595
653
|
batches: [],
|
|
596
654
|
iKeyMap: {}
|
|
597
655
|
};
|
|
@@ -600,7 +658,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
600
658
|
function _getEventBatch(iKey: string, latency: number, create: boolean) {
|
|
601
659
|
let batchQueue: IPostChannelBatchQueue = _batchQueues[latency];
|
|
602
660
|
if (!batchQueue) {
|
|
603
|
-
latency =
|
|
661
|
+
latency = EventLatencyValue.Normal;
|
|
604
662
|
batchQueue = _batchQueues[latency];
|
|
605
663
|
}
|
|
606
664
|
|
|
@@ -638,7 +696,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
638
696
|
const latency = event.latency;
|
|
639
697
|
let eventBatch = _getEventBatch(event.iKey, latency, true);
|
|
640
698
|
if (eventBatch.addEvent(event)) {
|
|
641
|
-
if (latency !==
|
|
699
|
+
if (latency !== EventLatencyValue.Immediate) {
|
|
642
700
|
_queueSize++;
|
|
643
701
|
|
|
644
702
|
// Check for auto flushing based on total events in the queue, but not for requeued or retry events
|
|
@@ -665,7 +723,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
665
723
|
let droppedEvents = eventBatch.split(0, dropNumber);
|
|
666
724
|
let droppedCount = droppedEvents.count();
|
|
667
725
|
if (droppedCount > 0) {
|
|
668
|
-
if (currentLatency ===
|
|
726
|
+
if (currentLatency === EventLatencyValue.Immediate) {
|
|
669
727
|
_immediateQueueSize -= droppedCount;
|
|
670
728
|
} else {
|
|
671
729
|
_queueSize -= droppedCount;
|
|
@@ -692,11 +750,11 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
692
750
|
function _resetQueueCounts() {
|
|
693
751
|
let immediateQueue = 0;
|
|
694
752
|
let normalQueue = 0;
|
|
695
|
-
for (let latency =
|
|
753
|
+
for (let latency = EventLatencyValue.Normal; latency <= EventLatencyValue.Immediate; latency++) {
|
|
696
754
|
let batchQueue: IPostChannelBatchQueue = _batchQueues[latency];
|
|
697
755
|
if (batchQueue && batchQueue.batches) {
|
|
698
756
|
arrForEach(batchQueue.batches, (theBatch) => {
|
|
699
|
-
if (latency ===
|
|
757
|
+
if (latency === EventLatencyValue.Immediate) {
|
|
700
758
|
immediateQueue += theBatch.count();
|
|
701
759
|
} else {
|
|
702
760
|
normalQueue += theBatch.count();
|
|
@@ -719,7 +777,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
719
777
|
if (!isAsync || _httpManager.canSendRequest()) {
|
|
720
778
|
doPerf(_self.core, () => "PostChannel._queueBatches", () => {
|
|
721
779
|
let droppedEvents = [];
|
|
722
|
-
let latencyToProcess =
|
|
780
|
+
let latencyToProcess = EventLatencyValue.Immediate;
|
|
723
781
|
while (latencyToProcess >= latency) {
|
|
724
782
|
let batchQueue: IPostChannelBatchQueue = _batchQueues[latencyToProcess];
|
|
725
783
|
if (batchQueue && batchQueue.batches && batchQueue.batches.length > 0) {
|
|
@@ -732,7 +790,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
732
790
|
eventsQueued = eventsQueued || (theBatch && theBatch.count() > 0);
|
|
733
791
|
}
|
|
734
792
|
|
|
735
|
-
if (latencyToProcess ===
|
|
793
|
+
if (latencyToProcess === EventLatencyValue.Immediate) {
|
|
736
794
|
_immediateQueueSize -= theBatch.count();
|
|
737
795
|
} else {
|
|
738
796
|
_queueSize -= theBatch.count();
|
|
@@ -773,7 +831,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
773
831
|
*/
|
|
774
832
|
function _flushImpl(callback: () => void, sendReason: SendRequestReason) {
|
|
775
833
|
// Add any additional queued events and cause all queued events to be sent asynchronously
|
|
776
|
-
_sendEventsForLatencyAndAbove(
|
|
834
|
+
_sendEventsForLatencyAndAbove(EventLatencyValue.Normal, EventSendType.Batched, sendReason);
|
|
777
835
|
|
|
778
836
|
_waitForIdleManager(() => {
|
|
779
837
|
// Only called AFTER the httpManager does not have any outstanding requests
|
|
@@ -841,7 +899,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
841
899
|
if (theEvent) {
|
|
842
900
|
// Check if the request being added back is for a sync event in which case mark it no longer a sync event
|
|
843
901
|
if (theEvent.sync) {
|
|
844
|
-
theEvent.latency =
|
|
902
|
+
theEvent.latency = EventLatencyValue.Immediate;
|
|
845
903
|
theEvent.sync = false;
|
|
846
904
|
}
|
|
847
905
|
|
|
@@ -874,8 +932,9 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
874
932
|
try {
|
|
875
933
|
notifyFunc.apply(manager, theArgs);
|
|
876
934
|
} catch (e) {
|
|
877
|
-
_self.diagLog()
|
|
878
|
-
|
|
935
|
+
_throwInternal(_self.diagLog(),
|
|
936
|
+
eLoggingSeverity.CRITICAL,
|
|
937
|
+
_eInternalMessageId.NotificationException,
|
|
879
938
|
evtName + " notification failed: " + e);
|
|
880
939
|
}
|
|
881
940
|
}
|
|
@@ -953,6 +1012,21 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
953
1012
|
_autoFlushBatchLimit = 0;
|
|
954
1013
|
}
|
|
955
1014
|
}
|
|
1015
|
+
|
|
1016
|
+
// Provided for backward compatibility they are not "expected" to be in current use but they are public
|
|
1017
|
+
objDefineAccessors(_self, "_setTimeoutOverride",
|
|
1018
|
+
() => _timeoutWrapper.set,
|
|
1019
|
+
(value: TimeoutSetFunc<any>) => {
|
|
1020
|
+
// Recreate the timeout wrapper
|
|
1021
|
+
_timeoutWrapper = createTimeoutWrapper(value, _timeoutWrapper.clear);
|
|
1022
|
+
});
|
|
1023
|
+
|
|
1024
|
+
objDefineAccessors(_self, "_clearTimeoutOverride",
|
|
1025
|
+
() => _timeoutWrapper.clear,
|
|
1026
|
+
(value: TimeoutClearFunc<any>) => {
|
|
1027
|
+
// Recreate the timeout wrapper
|
|
1028
|
+
_timeoutWrapper = createTimeoutWrapper(_timeoutWrapper.set, value);
|
|
1029
|
+
});
|
|
956
1030
|
});
|
|
957
1031
|
}
|
|
958
1032
|
|
|
@@ -987,13 +1061,6 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
987
1061
|
// @DynamicProtoStub - DO NOT add any code as this will be removed during packaging
|
|
988
1062
|
}
|
|
989
1063
|
|
|
990
|
-
/**
|
|
991
|
-
* Batch all current events in the queues and send them.
|
|
992
|
-
*/
|
|
993
|
-
public teardown() {
|
|
994
|
-
// @DynamicProtoStub - DO NOT add any code as this will be removed during packaging
|
|
995
|
-
}
|
|
996
|
-
|
|
997
1064
|
/**
|
|
998
1065
|
* Pause the transmission of any requests
|
|
999
1066
|
*/
|
package/src/RetryPolicy.ts
CHANGED
|
@@ -9,43 +9,38 @@ const BaseBackoff = 3000;
|
|
|
9
9
|
const MaxBackoff = 600000;
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|| (httpStatusCode == 501)
|
|
32
|
-
|| (httpStatusCode == 505));
|
|
33
|
-
/* tslint:enable:triple-equals */
|
|
34
|
-
}
|
|
12
|
+
* Determine if the request should be retried for the given status code.
|
|
13
|
+
* The below expression reads that we should only retry for:
|
|
14
|
+
* - HttpStatusCodes that are smaller than 300.
|
|
15
|
+
* - HttpStatusCodes greater or equal to 500 (except for 501-NotImplement
|
|
16
|
+
* and 505-HttpVersionNotSupport).
|
|
17
|
+
* - HttpStatusCode 408-RequestTimeout.
|
|
18
|
+
* - HttpStatusCode 429.
|
|
19
|
+
* This is based on Microsoft.WindowsAzure.Storage.RetryPolicies.ExponentialRetry class
|
|
20
|
+
* @param httpStatusCode - The status code returned for the request.
|
|
21
|
+
* @returns True if request should be retried, false otherwise.
|
|
22
|
+
*/
|
|
23
|
+
export function retryPolicyShouldRetryForStatus(httpStatusCode: number): boolean {
|
|
24
|
+
/* tslint:disable:triple-equals */
|
|
25
|
+
// Disabling triple-equals rule to avoid httpOverrides from failing because they are returning a string value
|
|
26
|
+
return !((httpStatusCode >= 300 && httpStatusCode < 500 && httpStatusCode != 408 && httpStatusCode != 429)
|
|
27
|
+
|| (httpStatusCode == 501)
|
|
28
|
+
|| (httpStatusCode == 505));
|
|
29
|
+
/* tslint:enable:triple-equals */
|
|
30
|
+
}
|
|
35
31
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
32
|
+
/**
|
|
33
|
+
* Gets the number of milliseconds to back off before retrying the request. The
|
|
34
|
+
* back off duration is exponentially scaled based on the number of retries already
|
|
35
|
+
* done for the request.
|
|
36
|
+
* @param retriesSoFar - The number of times the request has already been retried.
|
|
37
|
+
* @returns The back off duration for the request before it can be retried.
|
|
38
|
+
*/
|
|
39
|
+
export function retryPolicyGetMillisToBackoffForRetry(retriesSoFar: number): number {
|
|
40
|
+
let waitDuration = 0;
|
|
41
|
+
let minBackoff = BaseBackoff * RandomizationLowerThreshold;
|
|
42
|
+
let maxBackoff = BaseBackoff * RandomizationUpperThreshold;
|
|
43
|
+
let randomBackoff = Math.floor(Math.random() * (maxBackoff - minBackoff)) + minBackoff;
|
|
44
|
+
waitDuration = Math.pow(2, retriesSoFar) * randomBackoff;
|
|
45
|
+
return Math.min(waitDuration, MaxBackoff);
|
|
51
46
|
}
|