@microsoft/1ds-post-js 3.1.11 → 3.2.0
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.0.gbl.js} +1486 -786
- package/bundle/ms.post-3.2.0.gbl.js.map +1 -0
- package/bundle/ms.post-3.2.0.gbl.min.js +7 -0
- package/bundle/ms.post-3.2.0.gbl.min.js.map +1 -0
- package/bundle/ms.post-3.2.0.integrity.json +46 -0
- package/bundle/{ms.post-3.1.11.js → ms.post-3.2.0.js} +1486 -786
- package/bundle/ms.post-3.2.0.js.map +1 -0
- package/bundle/ms.post-3.2.0.min.js +7 -0
- package/bundle/ms.post-3.2.0.min.js.map +1 -0
- package/bundle/ms.post.gbl.js +1485 -785
- 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 +1485 -785
- 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 +177 -116
- 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.js +41 -36
- 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 +0 -4
- package/dist-esm/src/PostChannel.js +136 -92
- 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/typings/XDomainRequest.js +1 -1
- package/package.json +2 -2
- package/src/HttpManager.ts +43 -47
- package/src/PostChannel.ts +162 -114
- package/src/RetryPolicy.ts +33 -38
- 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
|
@@ -5,10 +5,15 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import {
|
|
7
7
|
BaseTelemetryPlugin, IChannelControls, IExtendedConfiguration, IExtendedAppInsightsCore,
|
|
8
|
-
|
|
9
|
-
IAppInsightsCore, isValueAssigned,
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
EventLatencyValue, NotificationManager, EventsDiscardedReason, IPlugin, ITelemetryItem,
|
|
9
|
+
IAppInsightsCore, isValueAssigned, setProcessTelemetryTimings, isWindowObjectAvailable,
|
|
10
|
+
IProcessTelemetryContext, SendRequestReason, arrForEach, eLoggingSeverity, _eExtendedInternalMessageId,
|
|
11
|
+
doPerf, objForEachKey, optimizeObject, isChromium, getWindow, EventSendType, isNumber, mergeEvtNamespace,
|
|
12
|
+
createUniqueNamespace, IProcessTelemetryUnloadContext, ITelemetryUnloadState,
|
|
13
|
+
addPageUnloadEventListener, addPageHideEventListener, addPageShowEventListener,
|
|
14
|
+
removePageUnloadEventListener, removePageHideEventListener, removePageShowEventListener,
|
|
15
|
+
_throwInternal,
|
|
16
|
+
_eInternalMessageId
|
|
12
17
|
} from "@microsoft/1ds-core-js";
|
|
13
18
|
import {
|
|
14
19
|
IChannelConfiguration, RT_PROFILE, NRT_PROFILE, IPostChannel,
|
|
@@ -17,7 +22,7 @@ import {
|
|
|
17
22
|
} from "./DataModels";
|
|
18
23
|
import { EventBatch } from "./EventBatch";
|
|
19
24
|
import { HttpManager } from "./HttpManager";
|
|
20
|
-
import
|
|
25
|
+
import { retryPolicyGetMillisToBackoffForRetry } from "./RetryPolicy";
|
|
21
26
|
import dynamicProto from "@microsoft/dynamicproto-js";
|
|
22
27
|
import { strMsaDeviceTicket } from "./Constants";
|
|
23
28
|
|
|
@@ -37,6 +42,8 @@ const strOverrideInstrumentationKey = "overrideInstrumentationKey";
|
|
|
37
42
|
const strMaxEventRetryAttempts = "maxEventRetryAttempts";
|
|
38
43
|
const strMaxUnloadEventRetryAttempts = "maxUnloadEventRetryAttempts";
|
|
39
44
|
|
|
45
|
+
const strAddUnloadCb = "addUnloadCb";
|
|
46
|
+
|
|
40
47
|
interface IPostChannelBatchQueue {
|
|
41
48
|
/**
|
|
42
49
|
* This is the actual queue of event batches
|
|
@@ -93,20 +100,10 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
93
100
|
let _disableXhrSync = false;
|
|
94
101
|
let _maxEventSendAttempts: number = MaxSendAttempts;
|
|
95
102
|
let _maxUnloadEventSendAttempts: number = MaxSyncUnloadSendAttempts;
|
|
103
|
+
let _evtNamespace: string | string[];
|
|
96
104
|
|
|
97
105
|
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
|
-
});
|
|
106
|
+
_initDefaults();
|
|
110
107
|
|
|
111
108
|
// Special internal method to allow the DebugPlugin to hook embedded objects
|
|
112
109
|
_self["_getDbgPlgTargets"] = () => {
|
|
@@ -117,63 +114,69 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
117
114
|
doPerf(core, () => "PostChannel:initialize", () => {
|
|
118
115
|
let extendedCore = core as IExtendedAppInsightsCore;
|
|
119
116
|
_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
|
-
|
|
117
|
+
try {
|
|
118
|
+
let hasAddUnloadCb = !!core[strAddUnloadCb];
|
|
119
|
+
_evtNamespace = mergeEvtNamespace(createUniqueNamespace(_self.identifier), core.evtNamespace && core.evtNamespace());
|
|
120
|
+
|
|
121
|
+
let ctx = _self._getTelCtx();
|
|
122
|
+
coreConfig.extensionConfig[_self.identifier] = coreConfig.extensionConfig[_self.identifier] || {};
|
|
123
|
+
_config = ctx.getExtCfg(_self.identifier);
|
|
124
|
+
_self._setTimeoutOverride = _config.setTimeoutOverride ? _config.setTimeoutOverride : setTimeout.bind(globalContext);
|
|
125
|
+
_self._clearTimeoutOverride = _config.clearTimeoutOverride ? _config.clearTimeoutOverride : clearTimeout.bind(globalContext);
|
|
126
|
+
|
|
127
|
+
// Only try and use the optimizeObject() if this appears to be a chromium based browser and it has not been explicitly disabled
|
|
128
|
+
_optimizeObject = !_config.disableOptimizeObj && isChromium();
|
|
129
|
+
|
|
130
|
+
_hookWParam(extendedCore);
|
|
131
|
+
|
|
132
|
+
if (_config.eventsLimitInMem > 0) {
|
|
133
|
+
_queueSizeLimit = _config.eventsLimitInMem;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (_config.immediateEventLimit > 0) {
|
|
137
|
+
_immediateQueueSizeLimit = _config.immediateEventLimit;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (_config.autoFlushEventsLimit > 0) {
|
|
141
|
+
_autoFlushEventsLimit = _config.autoFlushEventsLimit;
|
|
142
|
+
}
|
|
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
|
+
|
|
153
|
+
_setAutoLimits();
|
|
154
|
+
|
|
155
|
+
if (_config.httpXHROverride && _config.httpXHROverride.sendPOST) {
|
|
156
|
+
_xhrOverride = _config.httpXHROverride;
|
|
157
|
+
}
|
|
158
|
+
if (isValueAssigned(coreConfig.anonCookieName)) {
|
|
159
|
+
_httpManager.addQueryStringParameter("anoncknm", coreConfig.anonCookieName);
|
|
160
|
+
}
|
|
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, _evtNamespace);
|
|
173
|
+
addPageHideEventListener(_handleUnloadEvents, excludePageUnloadEvents, _evtNamespace);
|
|
174
|
+
addPageShowEventListener(_handleShowEvents, coreConfig.disablePageShowEvents, _evtNamespace);
|
|
175
|
+
} catch (e) {
|
|
176
|
+
// resetting the initialized state because of failure
|
|
177
|
+
_self.setInitialized(false);
|
|
178
|
+
throw e;
|
|
160
179
|
}
|
|
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
180
|
}, () => ({ coreConfig, core, extensions }));
|
|
178
181
|
};
|
|
179
182
|
|
|
@@ -216,6 +219,19 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
216
219
|
_self.processNext(event, itemCtx);
|
|
217
220
|
};
|
|
218
221
|
|
|
222
|
+
_self._doTeardown = (unloadCtx?: IProcessTelemetryUnloadContext, unloadState?: ITelemetryUnloadState) => {
|
|
223
|
+
_releaseAllQueues(EventSendType.SendBeacon, SendRequestReason.Unload);
|
|
224
|
+
_isTeardownCalled = true;
|
|
225
|
+
_httpManager.teardown();
|
|
226
|
+
|
|
227
|
+
removePageUnloadEventListener(null, _evtNamespace);
|
|
228
|
+
removePageHideEventListener(null, _evtNamespace);
|
|
229
|
+
removePageShowEventListener(null, _evtNamespace);
|
|
230
|
+
|
|
231
|
+
// Just register to remove all events associated with this namespace
|
|
232
|
+
_initDefaults();
|
|
233
|
+
};
|
|
234
|
+
|
|
219
235
|
function _hookWParam(extendedCore: IExtendedAppInsightsCore) {
|
|
220
236
|
var existingGetWParamMethod = extendedCore.getWParam;
|
|
221
237
|
extendedCore.getWParam = () => {
|
|
@@ -252,7 +268,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
252
268
|
}
|
|
253
269
|
// Add default latency
|
|
254
270
|
if (!event.latency) {
|
|
255
|
-
event.latency =
|
|
271
|
+
event.latency = EventLatencyValue.Normal;
|
|
256
272
|
}
|
|
257
273
|
|
|
258
274
|
// Remove extra AI properties if present
|
|
@@ -278,7 +294,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
278
294
|
// If the transmission is backed off then do not send synchronous events.
|
|
279
295
|
// We will convert these events to Real time latency instead.
|
|
280
296
|
if (_currentBackoffCount || _paused) {
|
|
281
|
-
event.latency =
|
|
297
|
+
event.latency = EventLatencyValue.RealTime;
|
|
282
298
|
event.sync = false;
|
|
283
299
|
} else {
|
|
284
300
|
// Log the event synchronously
|
|
@@ -300,7 +316,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
300
316
|
let evtLatency = event.latency;
|
|
301
317
|
let queueSize = _queueSize;
|
|
302
318
|
let queueLimit = _queueSizeLimit;
|
|
303
|
-
if (evtLatency ===
|
|
319
|
+
if (evtLatency === EventLatencyValue.Immediate) {
|
|
304
320
|
queueSize = _immediateQueueSize;
|
|
305
321
|
queueLimit = _immediateQueueSizeLimit;
|
|
306
322
|
}
|
|
@@ -310,11 +326,11 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
310
326
|
if (queueSize < queueLimit) {
|
|
311
327
|
eventDropped = !_addEventToProperQueue(event, append);
|
|
312
328
|
} else {
|
|
313
|
-
let dropLatency =
|
|
329
|
+
let dropLatency = EventLatencyValue.Normal;
|
|
314
330
|
let dropNumber = EventsDroppedAtOneTime;
|
|
315
|
-
if (evtLatency ===
|
|
331
|
+
if (evtLatency === EventLatencyValue.Immediate) {
|
|
316
332
|
// Only drop other immediate events as they are not technically sharing the general queue
|
|
317
|
-
dropLatency =
|
|
333
|
+
dropLatency = EventLatencyValue.Immediate;
|
|
318
334
|
dropNumber = 1;
|
|
319
335
|
}
|
|
320
336
|
|
|
@@ -341,7 +357,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
341
357
|
|
|
342
358
|
if (!doFlush && _autoFlushBatchLimit > 0) {
|
|
343
359
|
// Check the auto flush max batch size
|
|
344
|
-
for (let latency =
|
|
360
|
+
for (let latency = EventLatencyValue.Normal; !doFlush && latency <= EventLatencyValue.RealTime; latency++) {
|
|
345
361
|
let batchQueue: IPostChannelBatchQueue = _batchQueues[latency];
|
|
346
362
|
if (batchQueue && batchQueue.batches) {
|
|
347
363
|
arrForEach(batchQueue.batches, (theBatch) => {
|
|
@@ -357,12 +373,6 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
357
373
|
_performAutoFlush(true, doFlush);
|
|
358
374
|
};
|
|
359
375
|
|
|
360
|
-
_self.teardown = () => {
|
|
361
|
-
_releaseAllQueues(EventSendType.SendBeacon, SendRequestReason.Unload);
|
|
362
|
-
_isTeardownCalled = true;
|
|
363
|
-
_httpManager.teardown();
|
|
364
|
-
};
|
|
365
|
-
|
|
366
376
|
_self.pause = () => {
|
|
367
377
|
_clearScheduledTimer();
|
|
368
378
|
_paused = true;
|
|
@@ -418,7 +428,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
418
428
|
|
|
419
429
|
if (async) {
|
|
420
430
|
// Move all queued events to the HttpManager
|
|
421
|
-
_queueBatches(
|
|
431
|
+
_queueBatches(EventLatencyValue.Normal, EventSendType.Batched, sendReason);
|
|
422
432
|
|
|
423
433
|
// All events (should) have been queue -- lets just make sure the queue counts are correct to avoid queue exhaustion (previous bug #9685112)
|
|
424
434
|
_resetQueueCounts();
|
|
@@ -434,7 +444,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
434
444
|
}
|
|
435
445
|
} else {
|
|
436
446
|
// Now cause all queued events to be sent synchronously
|
|
437
|
-
_sendEventsForLatencyAndAbove(
|
|
447
|
+
_sendEventsForLatencyAndAbove(EventLatencyValue.Normal, EventSendType.Synchronous, sendReason);
|
|
438
448
|
|
|
439
449
|
if (callback !== null && callback !== undefined) {
|
|
440
450
|
callback();
|
|
@@ -494,7 +504,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
494
504
|
_immediateTimerId = _createTimer(() => {
|
|
495
505
|
_immediateTimerId = null;
|
|
496
506
|
// Only try to send direct events
|
|
497
|
-
_sendEventsForLatencyAndAbove(
|
|
507
|
+
_sendEventsForLatencyAndAbove(EventLatencyValue.Immediate, EventSendType.Batched, SendRequestReason.NormalSchedule);
|
|
498
508
|
_scheduleTimer();
|
|
499
509
|
}, immediateTimeOut);
|
|
500
510
|
}
|
|
@@ -506,7 +516,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
506
516
|
if (_hasEvents()) {
|
|
507
517
|
_scheduledTimerId = _createTimer(() => {
|
|
508
518
|
_scheduledTimerId = null;
|
|
509
|
-
_sendEventsForLatencyAndAbove(_timerCount === 0 ?
|
|
519
|
+
_sendEventsForLatencyAndAbove(_timerCount === 0 ? EventLatencyValue.RealTime : EventLatencyValue.Normal, EventSendType.Batched, SendRequestReason.NormalSchedule);
|
|
510
520
|
|
|
511
521
|
// Increment the count for next cycle
|
|
512
522
|
_timerCount++;
|
|
@@ -536,6 +546,50 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
536
546
|
}
|
|
537
547
|
};
|
|
538
548
|
|
|
549
|
+
function _initDefaults() {
|
|
550
|
+
_config = null;
|
|
551
|
+
_isTeardownCalled = false;
|
|
552
|
+
_flushCallbackQueue = [];
|
|
553
|
+
_flushCallbackTimerId = null;
|
|
554
|
+
_paused = false;
|
|
555
|
+
_immediateQueueSize = 0;
|
|
556
|
+
_immediateQueueSizeLimit = 500;
|
|
557
|
+
_queueSize = 0;
|
|
558
|
+
_queueSizeLimit = 10000;
|
|
559
|
+
_profiles = {};
|
|
560
|
+
_currentProfile = RT_PROFILE;
|
|
561
|
+
_scheduledTimerId = null;
|
|
562
|
+
_immediateTimerId = null;
|
|
563
|
+
_currentBackoffCount = 0;
|
|
564
|
+
_timerCount = 0;
|
|
565
|
+
_xhrOverride = null;
|
|
566
|
+
_batchQueues = {};
|
|
567
|
+
_autoFlushEventsLimit = undefined;
|
|
568
|
+
|
|
569
|
+
// either MaxBatchSize * (1+ Max Connections) or _queueLimit / 6 (where 3 latency Queues [normal, realtime, cost deferred] * 2 [allow half full -- allow for retry])
|
|
570
|
+
_autoFlushBatchLimit = 0;
|
|
571
|
+
_delayedBatchSendLatency = -1;
|
|
572
|
+
_delayedBatchReason = null;
|
|
573
|
+
_optimizeObject = true;
|
|
574
|
+
_isPageUnloadTriggered = false;
|
|
575
|
+
_disableXhrSync = false;
|
|
576
|
+
_maxEventSendAttempts = MaxSendAttempts;
|
|
577
|
+
_maxUnloadEventSendAttempts = MaxSyncUnloadSendAttempts;
|
|
578
|
+
_evtNamespace = null;
|
|
579
|
+
_httpManager = new HttpManager(MaxNumberEventPerBatch, MaxConnections, MaxRequestRetriesBeforeBackoff, {
|
|
580
|
+
requeue: _requeueEvents,
|
|
581
|
+
send: _sendingEvent,
|
|
582
|
+
sent: _eventsSentEvent,
|
|
583
|
+
drop: _eventsDropped,
|
|
584
|
+
rspFail: _eventsResponseFail,
|
|
585
|
+
oth: _otherEvent
|
|
586
|
+
});
|
|
587
|
+
|
|
588
|
+
_initializeProfiles();
|
|
589
|
+
_clearQueues();
|
|
590
|
+
_setAutoLimits();
|
|
591
|
+
}
|
|
592
|
+
|
|
539
593
|
function _createTimer(theTimerFunc: () => void, timeOut: number): any {
|
|
540
594
|
// If the transmission is backed off make the timer at least 1 sec to allow for back off.
|
|
541
595
|
if (timeOut === 0 && _currentBackoffCount) {
|
|
@@ -544,7 +598,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
544
598
|
|
|
545
599
|
let timerMultiplier = 1000;
|
|
546
600
|
if (_currentBackoffCount) {
|
|
547
|
-
timerMultiplier =
|
|
601
|
+
timerMultiplier = retryPolicyGetMillisToBackoffForRetry(_currentBackoffCount - 1);
|
|
548
602
|
}
|
|
549
603
|
|
|
550
604
|
return _self._setTimeoutOverride(theTimerFunc, timeOut * timerMultiplier);
|
|
@@ -569,7 +623,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
569
623
|
|
|
570
624
|
if (!_paused) {
|
|
571
625
|
// Queue all the remaining requests to be sent. The requests will be sent using HTML5 Beacons if they are available.
|
|
572
|
-
_sendEventsForLatencyAndAbove(
|
|
626
|
+
_sendEventsForLatencyAndAbove(EventLatencyValue.Normal, sendType, sendReason);
|
|
573
627
|
}
|
|
574
628
|
}
|
|
575
629
|
|
|
@@ -579,19 +633,19 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
579
633
|
* after flush are stored separately till we flush the current events.
|
|
580
634
|
*/
|
|
581
635
|
function _clearQueues() {
|
|
582
|
-
_batchQueues[
|
|
636
|
+
_batchQueues[EventLatencyValue.Immediate] = {
|
|
583
637
|
batches: [],
|
|
584
638
|
iKeyMap: {}
|
|
585
639
|
};
|
|
586
|
-
_batchQueues[
|
|
640
|
+
_batchQueues[EventLatencyValue.RealTime] = {
|
|
587
641
|
batches: [],
|
|
588
642
|
iKeyMap: {}
|
|
589
643
|
};
|
|
590
|
-
_batchQueues[
|
|
644
|
+
_batchQueues[EventLatencyValue.CostDeferred] = {
|
|
591
645
|
batches: [],
|
|
592
646
|
iKeyMap: {}
|
|
593
647
|
};
|
|
594
|
-
_batchQueues[
|
|
648
|
+
_batchQueues[EventLatencyValue.Normal] = {
|
|
595
649
|
batches: [],
|
|
596
650
|
iKeyMap: {}
|
|
597
651
|
};
|
|
@@ -600,7 +654,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
600
654
|
function _getEventBatch(iKey: string, latency: number, create: boolean) {
|
|
601
655
|
let batchQueue: IPostChannelBatchQueue = _batchQueues[latency];
|
|
602
656
|
if (!batchQueue) {
|
|
603
|
-
latency =
|
|
657
|
+
latency = EventLatencyValue.Normal;
|
|
604
658
|
batchQueue = _batchQueues[latency];
|
|
605
659
|
}
|
|
606
660
|
|
|
@@ -638,7 +692,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
638
692
|
const latency = event.latency;
|
|
639
693
|
let eventBatch = _getEventBatch(event.iKey, latency, true);
|
|
640
694
|
if (eventBatch.addEvent(event)) {
|
|
641
|
-
if (latency !==
|
|
695
|
+
if (latency !== EventLatencyValue.Immediate) {
|
|
642
696
|
_queueSize++;
|
|
643
697
|
|
|
644
698
|
// Check for auto flushing based on total events in the queue, but not for requeued or retry events
|
|
@@ -665,7 +719,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
665
719
|
let droppedEvents = eventBatch.split(0, dropNumber);
|
|
666
720
|
let droppedCount = droppedEvents.count();
|
|
667
721
|
if (droppedCount > 0) {
|
|
668
|
-
if (currentLatency ===
|
|
722
|
+
if (currentLatency === EventLatencyValue.Immediate) {
|
|
669
723
|
_immediateQueueSize -= droppedCount;
|
|
670
724
|
} else {
|
|
671
725
|
_queueSize -= droppedCount;
|
|
@@ -692,11 +746,11 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
692
746
|
function _resetQueueCounts() {
|
|
693
747
|
let immediateQueue = 0;
|
|
694
748
|
let normalQueue = 0;
|
|
695
|
-
for (let latency =
|
|
749
|
+
for (let latency = EventLatencyValue.Normal; latency <= EventLatencyValue.Immediate; latency++) {
|
|
696
750
|
let batchQueue: IPostChannelBatchQueue = _batchQueues[latency];
|
|
697
751
|
if (batchQueue && batchQueue.batches) {
|
|
698
752
|
arrForEach(batchQueue.batches, (theBatch) => {
|
|
699
|
-
if (latency ===
|
|
753
|
+
if (latency === EventLatencyValue.Immediate) {
|
|
700
754
|
immediateQueue += theBatch.count();
|
|
701
755
|
} else {
|
|
702
756
|
normalQueue += theBatch.count();
|
|
@@ -719,7 +773,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
719
773
|
if (!isAsync || _httpManager.canSendRequest()) {
|
|
720
774
|
doPerf(_self.core, () => "PostChannel._queueBatches", () => {
|
|
721
775
|
let droppedEvents = [];
|
|
722
|
-
let latencyToProcess =
|
|
776
|
+
let latencyToProcess = EventLatencyValue.Immediate;
|
|
723
777
|
while (latencyToProcess >= latency) {
|
|
724
778
|
let batchQueue: IPostChannelBatchQueue = _batchQueues[latencyToProcess];
|
|
725
779
|
if (batchQueue && batchQueue.batches && batchQueue.batches.length > 0) {
|
|
@@ -732,7 +786,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
732
786
|
eventsQueued = eventsQueued || (theBatch && theBatch.count() > 0);
|
|
733
787
|
}
|
|
734
788
|
|
|
735
|
-
if (latencyToProcess ===
|
|
789
|
+
if (latencyToProcess === EventLatencyValue.Immediate) {
|
|
736
790
|
_immediateQueueSize -= theBatch.count();
|
|
737
791
|
} else {
|
|
738
792
|
_queueSize -= theBatch.count();
|
|
@@ -773,7 +827,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
773
827
|
*/
|
|
774
828
|
function _flushImpl(callback: () => void, sendReason: SendRequestReason) {
|
|
775
829
|
// Add any additional queued events and cause all queued events to be sent asynchronously
|
|
776
|
-
_sendEventsForLatencyAndAbove(
|
|
830
|
+
_sendEventsForLatencyAndAbove(EventLatencyValue.Normal, EventSendType.Batched, sendReason);
|
|
777
831
|
|
|
778
832
|
_waitForIdleManager(() => {
|
|
779
833
|
// Only called AFTER the httpManager does not have any outstanding requests
|
|
@@ -841,7 +895,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
841
895
|
if (theEvent) {
|
|
842
896
|
// Check if the request being added back is for a sync event in which case mark it no longer a sync event
|
|
843
897
|
if (theEvent.sync) {
|
|
844
|
-
theEvent.latency =
|
|
898
|
+
theEvent.latency = EventLatencyValue.Immediate;
|
|
845
899
|
theEvent.sync = false;
|
|
846
900
|
}
|
|
847
901
|
|
|
@@ -874,8 +928,9 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
874
928
|
try {
|
|
875
929
|
notifyFunc.apply(manager, theArgs);
|
|
876
930
|
} catch (e) {
|
|
877
|
-
_self.diagLog()
|
|
878
|
-
|
|
931
|
+
_throwInternal(_self.diagLog(),
|
|
932
|
+
eLoggingSeverity.CRITICAL,
|
|
933
|
+
_eInternalMessageId.NotificationException,
|
|
879
934
|
evtName + " notification failed: " + e);
|
|
880
935
|
}
|
|
881
936
|
}
|
|
@@ -987,13 +1042,6 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
987
1042
|
// @DynamicProtoStub - DO NOT add any code as this will be removed during packaging
|
|
988
1043
|
}
|
|
989
1044
|
|
|
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
1045
|
/**
|
|
998
1046
|
* Pause the transmission of any requests
|
|
999
1047
|
*/
|
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
|
}
|