@microsoft/1ds-post-js 3.1.10 → 3.2.1
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 +124 -6
- package/bundle/{ms.post-3.1.10.gbl.js → ms.post-3.2.1.gbl.js} +1502 -725
- package/bundle/ms.post-3.2.1.gbl.js.map +1 -0
- package/bundle/ms.post-3.2.1.gbl.min.js +7 -0
- package/bundle/ms.post-3.2.1.gbl.min.js.map +1 -0
- package/bundle/ms.post-3.2.1.integrity.json +46 -0
- package/bundle/{ms.post-3.1.10.js → ms.post-3.2.1.js} +1502 -725
- package/bundle/ms.post-3.2.1.js.map +1 -0
- package/bundle/ms.post-3.2.1.min.js +7 -0
- package/bundle/ms.post-3.2.1.min.js.map +1 -0
- package/bundle/ms.post.gbl.js +1501 -724
- 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 +1501 -724
- 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 +264 -149
- 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 +102 -58
- 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 +171 -104
- 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/Constants.ts +1 -0
- package/src/DataModels.ts +62 -1
- package/src/HttpManager.ts +110 -69
- package/src/PostChannel.ts +203 -127
- package/src/RetryPolicy.ts +33 -38
- 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/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
|
|
|
@@ -25,14 +30,20 @@ const FlushCheckTimer = 0.250; // This needs to be in seconds, so this
|
|
|
25
30
|
const MaxNumberEventPerBatch = 500;
|
|
26
31
|
const EventsDroppedAtOneTime = 20;
|
|
27
32
|
const MaxSendAttempts = 6;
|
|
33
|
+
const MaxSyncUnloadSendAttempts = 2; // Assuming 2 based on beforeunload and unload
|
|
28
34
|
const MaxBackoffCount = 4;
|
|
29
35
|
const globalContext = isWindowObjectAvailable ? window : this;
|
|
30
36
|
const MaxConnections = 2;
|
|
31
|
-
const
|
|
37
|
+
const MaxRequestRetriesBeforeBackoff = 1;
|
|
32
38
|
|
|
33
39
|
const strEventsDiscarded = "eventsDiscarded";
|
|
34
40
|
const strOverrideInstrumentationKey = "overrideInstrumentationKey";
|
|
35
41
|
|
|
42
|
+
const strMaxEventRetryAttempts = "maxEventRetryAttempts";
|
|
43
|
+
const strMaxUnloadEventRetryAttempts = "maxUnloadEventRetryAttempts";
|
|
44
|
+
|
|
45
|
+
const strAddUnloadCb = "addUnloadCb";
|
|
46
|
+
|
|
36
47
|
interface IPostChannelBatchQueue {
|
|
37
48
|
/**
|
|
38
49
|
* This is the actual queue of event batches
|
|
@@ -86,20 +97,13 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
86
97
|
let _delayedBatchReason: SendRequestReason;
|
|
87
98
|
let _optimizeObject: boolean = true;
|
|
88
99
|
let _isPageUnloadTriggered = false;
|
|
100
|
+
let _disableXhrSync = false;
|
|
101
|
+
let _maxEventSendAttempts: number = MaxSendAttempts;
|
|
102
|
+
let _maxUnloadEventSendAttempts: number = MaxSyncUnloadSendAttempts;
|
|
103
|
+
let _evtNamespace: string | string[];
|
|
89
104
|
|
|
90
105
|
dynamicProto(PostChannel, this, (_self, _base) => {
|
|
91
|
-
|
|
92
|
-
_clearQueues();
|
|
93
|
-
_setAutoLimits();
|
|
94
|
-
|
|
95
|
-
_httpManager = new HttpManager(MaxNumberEventPerBatch, MaxConnections, MaxRetries, {
|
|
96
|
-
requeue: _requeueEvents,
|
|
97
|
-
send: _sendingEvent,
|
|
98
|
-
sent: _eventsSentEvent,
|
|
99
|
-
drop: _eventsDropped,
|
|
100
|
-
rspFail: _eventsResponseFail,
|
|
101
|
-
oth: _otherEvent
|
|
102
|
-
});
|
|
106
|
+
_initDefaults();
|
|
103
107
|
|
|
104
108
|
// Special internal method to allow the DebugPlugin to hook embedded objects
|
|
105
109
|
_self["_getDbgPlgTargets"] = () => {
|
|
@@ -110,76 +114,69 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
110
114
|
doPerf(core, () => "PostChannel:initialize", () => {
|
|
111
115
|
let extendedCore = core as IExtendedAppInsightsCore;
|
|
112
116
|
_base.initialize(coreConfig, core, extensions);
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
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;
|
|
128
134
|
}
|
|
129
|
-
|
|
130
|
-
|
|
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
|
-
_setAutoLimits();
|
|
145
|
-
|
|
146
|
-
if (_config.httpXHROverride && _config.httpXHROverride.sendPOST) {
|
|
147
|
-
_xhrOverride = _config.httpXHROverride;
|
|
148
|
-
}
|
|
149
|
-
if (isValueAssigned(coreConfig.anonCookieName)) {
|
|
150
|
-
_httpManager.addQueryStringParameter("anoncknm", coreConfig.anonCookieName);
|
|
151
|
-
}
|
|
152
|
-
_httpManager.sendHook = _config.payloadPreprocessor;
|
|
153
|
-
_httpManager.sendListener = _config.payloadListener;
|
|
154
|
-
|
|
155
|
-
// Override endpointUrl if provided in Post config
|
|
156
|
-
let endpointUrl = _config.overrideEndpointUrl ? _config.overrideEndpointUrl : coreConfig.endpointUrl;
|
|
157
|
-
_self._notificationManager = coreConfig.extensionConfig.NotificationManager;
|
|
158
|
-
_httpManager.initialize(endpointUrl, _self.core as IExtendedAppInsightsCore, _self, _xhrOverride, _config);
|
|
159
|
-
|
|
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);
|
|
135
|
+
|
|
136
|
+
if (_config.immediateEventLimit > 0) {
|
|
137
|
+
_immediateQueueSizeLimit = _config.immediateEventLimit;
|
|
166
138
|
}
|
|
167
|
-
|
|
168
|
-
|
|
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;
|
|
169
179
|
}
|
|
170
|
-
|
|
171
|
-
let excludePageUnloadEvents = coreConfig.disablePageUnloadEvents || [];
|
|
172
|
-
|
|
173
|
-
// When running in Web browsers try to send all telemetry if page is unloaded
|
|
174
|
-
addPageUnloadEventListener(_handleUnloadEvents, excludePageUnloadEvents);
|
|
175
|
-
addPageHideEventListener(_handleUnloadEvents, excludePageUnloadEvents);
|
|
176
|
-
addPageShowEventListener((evt) => {
|
|
177
|
-
// Handle the page becoming visible again
|
|
178
|
-
_isPageUnloadTriggered = false;
|
|
179
|
-
_httpManager.setUnloading(_isPageUnloadTriggered);
|
|
180
|
-
}, coreConfig.disablePageShowEvents);
|
|
181
|
-
|
|
182
|
-
_self.setInitialized(true);
|
|
183
180
|
}, () => ({ coreConfig, core, extensions }));
|
|
184
181
|
};
|
|
185
182
|
|
|
@@ -222,6 +219,48 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
222
219
|
_self.processNext(event, itemCtx);
|
|
223
220
|
};
|
|
224
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
|
+
|
|
235
|
+
function _hookWParam(extendedCore: IExtendedAppInsightsCore) {
|
|
236
|
+
var existingGetWParamMethod = extendedCore.getWParam;
|
|
237
|
+
extendedCore.getWParam = () => {
|
|
238
|
+
var wparam = 0;
|
|
239
|
+
if (_config.ignoreMc1Ms0CookieProcessing) {
|
|
240
|
+
wparam = wparam | 2;
|
|
241
|
+
}
|
|
242
|
+
return wparam | existingGetWParamMethod();
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// Moving event handlers out from the initialize closure so that any local variables can be garbage collected
|
|
247
|
+
function _handleUnloadEvents(evt: any) {
|
|
248
|
+
let theEvt = evt || getWindow().event; // IE 8 does not pass the event
|
|
249
|
+
if (theEvt.type !== "beforeunload") {
|
|
250
|
+
// Only set the unload trigger if not beforeunload event as beforeunload can be cancelled while the other events can't
|
|
251
|
+
_isPageUnloadTriggered = true;
|
|
252
|
+
_httpManager.setUnloading(_isPageUnloadTriggered);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
_releaseAllQueues(EventSendType.SendBeacon, SendRequestReason.Unload);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
function _handleShowEvents(evt: any) {
|
|
259
|
+
// Handle the page becoming visible again
|
|
260
|
+
_isPageUnloadTriggered = false;
|
|
261
|
+
_httpManager.setUnloading(_isPageUnloadTriggered);
|
|
262
|
+
}
|
|
263
|
+
|
|
225
264
|
function _addEventToQueues(event: IPostTransmissionTelemetryItem, append: boolean) {
|
|
226
265
|
// If send attempt field is undefined we should set it to 0.
|
|
227
266
|
if (!event.sendAttempt) {
|
|
@@ -229,7 +268,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
229
268
|
}
|
|
230
269
|
// Add default latency
|
|
231
270
|
if (!event.latency) {
|
|
232
|
-
event.latency =
|
|
271
|
+
event.latency = EventLatencyValue.Normal;
|
|
233
272
|
}
|
|
234
273
|
|
|
235
274
|
// Remove extra AI properties if present
|
|
@@ -255,7 +294,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
255
294
|
// If the transmission is backed off then do not send synchronous events.
|
|
256
295
|
// We will convert these events to Real time latency instead.
|
|
257
296
|
if (_currentBackoffCount || _paused) {
|
|
258
|
-
event.latency =
|
|
297
|
+
event.latency = EventLatencyValue.RealTime;
|
|
259
298
|
event.sync = false;
|
|
260
299
|
} else {
|
|
261
300
|
// Log the event synchronously
|
|
@@ -277,7 +316,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
277
316
|
let evtLatency = event.latency;
|
|
278
317
|
let queueSize = _queueSize;
|
|
279
318
|
let queueLimit = _queueSizeLimit;
|
|
280
|
-
if (evtLatency ===
|
|
319
|
+
if (evtLatency === EventLatencyValue.Immediate) {
|
|
281
320
|
queueSize = _immediateQueueSize;
|
|
282
321
|
queueLimit = _immediateQueueSizeLimit;
|
|
283
322
|
}
|
|
@@ -287,11 +326,11 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
287
326
|
if (queueSize < queueLimit) {
|
|
288
327
|
eventDropped = !_addEventToProperQueue(event, append);
|
|
289
328
|
} else {
|
|
290
|
-
let dropLatency =
|
|
329
|
+
let dropLatency = EventLatencyValue.Normal;
|
|
291
330
|
let dropNumber = EventsDroppedAtOneTime;
|
|
292
|
-
if (evtLatency ===
|
|
331
|
+
if (evtLatency === EventLatencyValue.Immediate) {
|
|
293
332
|
// Only drop other immediate events as they are not technically sharing the general queue
|
|
294
|
-
dropLatency =
|
|
333
|
+
dropLatency = EventLatencyValue.Immediate;
|
|
295
334
|
dropNumber = 1;
|
|
296
335
|
}
|
|
297
336
|
|
|
@@ -318,7 +357,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
318
357
|
|
|
319
358
|
if (!doFlush && _autoFlushBatchLimit > 0) {
|
|
320
359
|
// Check the auto flush max batch size
|
|
321
|
-
for (let latency =
|
|
360
|
+
for (let latency = EventLatencyValue.Normal; !doFlush && latency <= EventLatencyValue.RealTime; latency++) {
|
|
322
361
|
let batchQueue: IPostChannelBatchQueue = _batchQueues[latency];
|
|
323
362
|
if (batchQueue && batchQueue.batches) {
|
|
324
363
|
arrForEach(batchQueue.batches, (theBatch) => {
|
|
@@ -334,12 +373,6 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
334
373
|
_performAutoFlush(true, doFlush);
|
|
335
374
|
};
|
|
336
375
|
|
|
337
|
-
_self.teardown = () => {
|
|
338
|
-
_releaseAllQueues(EventSendType.SendBeacon, SendRequestReason.Unload);
|
|
339
|
-
_isTeardownCalled = true;
|
|
340
|
-
_httpManager.teardown();
|
|
341
|
-
};
|
|
342
|
-
|
|
343
376
|
_self.pause = () => {
|
|
344
377
|
_clearScheduledTimer();
|
|
345
378
|
_paused = true;
|
|
@@ -395,7 +428,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
395
428
|
|
|
396
429
|
if (async) {
|
|
397
430
|
// Move all queued events to the HttpManager
|
|
398
|
-
_queueBatches(
|
|
431
|
+
_queueBatches(EventLatencyValue.Normal, EventSendType.Batched, sendReason);
|
|
399
432
|
|
|
400
433
|
// All events (should) have been queue -- lets just make sure the queue counts are correct to avoid queue exhaustion (previous bug #9685112)
|
|
401
434
|
_resetQueueCounts();
|
|
@@ -411,7 +444,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
411
444
|
}
|
|
412
445
|
} else {
|
|
413
446
|
// Now cause all queued events to be sent synchronously
|
|
414
|
-
_sendEventsForLatencyAndAbove(
|
|
447
|
+
_sendEventsForLatencyAndAbove(EventLatencyValue.Normal, EventSendType.Synchronous, sendReason);
|
|
415
448
|
|
|
416
449
|
if (callback !== null && callback !== undefined) {
|
|
417
450
|
callback();
|
|
@@ -471,7 +504,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
471
504
|
_immediateTimerId = _createTimer(() => {
|
|
472
505
|
_immediateTimerId = null;
|
|
473
506
|
// Only try to send direct events
|
|
474
|
-
_sendEventsForLatencyAndAbove(
|
|
507
|
+
_sendEventsForLatencyAndAbove(EventLatencyValue.Immediate, EventSendType.Batched, SendRequestReason.NormalSchedule);
|
|
475
508
|
_scheduleTimer();
|
|
476
509
|
}, immediateTimeOut);
|
|
477
510
|
}
|
|
@@ -483,7 +516,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
483
516
|
if (_hasEvents()) {
|
|
484
517
|
_scheduledTimerId = _createTimer(() => {
|
|
485
518
|
_scheduledTimerId = null;
|
|
486
|
-
_sendEventsForLatencyAndAbove(_timerCount === 0 ?
|
|
519
|
+
_sendEventsForLatencyAndAbove(_timerCount === 0 ? EventLatencyValue.RealTime : EventLatencyValue.Normal, EventSendType.Batched, SendRequestReason.NormalSchedule);
|
|
487
520
|
|
|
488
521
|
// Increment the count for next cycle
|
|
489
522
|
_timerCount++;
|
|
@@ -513,6 +546,50 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
513
546
|
}
|
|
514
547
|
};
|
|
515
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
|
+
|
|
516
593
|
function _createTimer(theTimerFunc: () => void, timeOut: number): any {
|
|
517
594
|
// If the transmission is backed off make the timer at least 1 sec to allow for back off.
|
|
518
595
|
if (timeOut === 0 && _currentBackoffCount) {
|
|
@@ -521,7 +598,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
521
598
|
|
|
522
599
|
let timerMultiplier = 1000;
|
|
523
600
|
if (_currentBackoffCount) {
|
|
524
|
-
timerMultiplier =
|
|
601
|
+
timerMultiplier = retryPolicyGetMillisToBackoffForRetry(_currentBackoffCount - 1);
|
|
525
602
|
}
|
|
526
603
|
|
|
527
604
|
return _self._setTimeoutOverride(theTimerFunc, timeOut * timerMultiplier);
|
|
@@ -546,7 +623,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
546
623
|
|
|
547
624
|
if (!_paused) {
|
|
548
625
|
// Queue all the remaining requests to be sent. The requests will be sent using HTML5 Beacons if they are available.
|
|
549
|
-
_sendEventsForLatencyAndAbove(
|
|
626
|
+
_sendEventsForLatencyAndAbove(EventLatencyValue.Normal, sendType, sendReason);
|
|
550
627
|
}
|
|
551
628
|
}
|
|
552
629
|
|
|
@@ -556,19 +633,19 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
556
633
|
* after flush are stored separately till we flush the current events.
|
|
557
634
|
*/
|
|
558
635
|
function _clearQueues() {
|
|
559
|
-
_batchQueues[
|
|
636
|
+
_batchQueues[EventLatencyValue.Immediate] = {
|
|
560
637
|
batches: [],
|
|
561
638
|
iKeyMap: {}
|
|
562
639
|
};
|
|
563
|
-
_batchQueues[
|
|
640
|
+
_batchQueues[EventLatencyValue.RealTime] = {
|
|
564
641
|
batches: [],
|
|
565
642
|
iKeyMap: {}
|
|
566
643
|
};
|
|
567
|
-
_batchQueues[
|
|
644
|
+
_batchQueues[EventLatencyValue.CostDeferred] = {
|
|
568
645
|
batches: [],
|
|
569
646
|
iKeyMap: {}
|
|
570
647
|
};
|
|
571
|
-
_batchQueues[
|
|
648
|
+
_batchQueues[EventLatencyValue.Normal] = {
|
|
572
649
|
batches: [],
|
|
573
650
|
iKeyMap: {}
|
|
574
651
|
};
|
|
@@ -577,7 +654,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
577
654
|
function _getEventBatch(iKey: string, latency: number, create: boolean) {
|
|
578
655
|
let batchQueue: IPostChannelBatchQueue = _batchQueues[latency];
|
|
579
656
|
if (!batchQueue) {
|
|
580
|
-
latency =
|
|
657
|
+
latency = EventLatencyValue.Normal;
|
|
581
658
|
batchQueue = _batchQueues[latency];
|
|
582
659
|
}
|
|
583
660
|
|
|
@@ -615,7 +692,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
615
692
|
const latency = event.latency;
|
|
616
693
|
let eventBatch = _getEventBatch(event.iKey, latency, true);
|
|
617
694
|
if (eventBatch.addEvent(event)) {
|
|
618
|
-
if (latency !==
|
|
695
|
+
if (latency !== EventLatencyValue.Immediate) {
|
|
619
696
|
_queueSize++;
|
|
620
697
|
|
|
621
698
|
// Check for auto flushing based on total events in the queue, but not for requeued or retry events
|
|
@@ -642,7 +719,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
642
719
|
let droppedEvents = eventBatch.split(0, dropNumber);
|
|
643
720
|
let droppedCount = droppedEvents.count();
|
|
644
721
|
if (droppedCount > 0) {
|
|
645
|
-
if (currentLatency ===
|
|
722
|
+
if (currentLatency === EventLatencyValue.Immediate) {
|
|
646
723
|
_immediateQueueSize -= droppedCount;
|
|
647
724
|
} else {
|
|
648
725
|
_queueSize -= droppedCount;
|
|
@@ -669,11 +746,11 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
669
746
|
function _resetQueueCounts() {
|
|
670
747
|
let immediateQueue = 0;
|
|
671
748
|
let normalQueue = 0;
|
|
672
|
-
for (let latency =
|
|
749
|
+
for (let latency = EventLatencyValue.Normal; latency <= EventLatencyValue.Immediate; latency++) {
|
|
673
750
|
let batchQueue: IPostChannelBatchQueue = _batchQueues[latency];
|
|
674
751
|
if (batchQueue && batchQueue.batches) {
|
|
675
752
|
arrForEach(batchQueue.batches, (theBatch) => {
|
|
676
|
-
if (latency ===
|
|
753
|
+
if (latency === EventLatencyValue.Immediate) {
|
|
677
754
|
immediateQueue += theBatch.count();
|
|
678
755
|
} else {
|
|
679
756
|
normalQueue += theBatch.count();
|
|
@@ -696,7 +773,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
696
773
|
if (!isAsync || _httpManager.canSendRequest()) {
|
|
697
774
|
doPerf(_self.core, () => "PostChannel._queueBatches", () => {
|
|
698
775
|
let droppedEvents = [];
|
|
699
|
-
let latencyToProcess =
|
|
776
|
+
let latencyToProcess = EventLatencyValue.Immediate;
|
|
700
777
|
while (latencyToProcess >= latency) {
|
|
701
778
|
let batchQueue: IPostChannelBatchQueue = _batchQueues[latencyToProcess];
|
|
702
779
|
if (batchQueue && batchQueue.batches && batchQueue.batches.length > 0) {
|
|
@@ -709,7 +786,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
709
786
|
eventsQueued = eventsQueued || (theBatch && theBatch.count() > 0);
|
|
710
787
|
}
|
|
711
788
|
|
|
712
|
-
if (latencyToProcess ===
|
|
789
|
+
if (latencyToProcess === EventLatencyValue.Immediate) {
|
|
713
790
|
_immediateQueueSize -= theBatch.count();
|
|
714
791
|
} else {
|
|
715
792
|
_queueSize -= theBatch.count();
|
|
@@ -750,7 +827,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
750
827
|
*/
|
|
751
828
|
function _flushImpl(callback: () => void, sendReason: SendRequestReason) {
|
|
752
829
|
// Add any additional queued events and cause all queued events to be sent asynchronously
|
|
753
|
-
_sendEventsForLatencyAndAbove(
|
|
830
|
+
_sendEventsForLatencyAndAbove(EventLatencyValue.Normal, EventSendType.Batched, sendReason);
|
|
754
831
|
|
|
755
832
|
_waitForIdleManager(() => {
|
|
756
833
|
// Only called AFTER the httpManager does not have any outstanding requests
|
|
@@ -805,6 +882,11 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
805
882
|
*/
|
|
806
883
|
function _requeueEvents(batches: EventBatch[], reason?: number) {
|
|
807
884
|
let droppedEvents: IPostTransmissionTelemetryItem[] = [];
|
|
885
|
+
let maxSendAttempts = _maxEventSendAttempts;
|
|
886
|
+
if (_isPageUnloadTriggered) {
|
|
887
|
+
// If a page unlaod has been triggered reduce the number of times we try to "retry"
|
|
888
|
+
maxSendAttempts = _maxUnloadEventSendAttempts;
|
|
889
|
+
}
|
|
808
890
|
|
|
809
891
|
arrForEach(batches, (theBatch) => {
|
|
810
892
|
if (theBatch && theBatch.count() > 0) {
|
|
@@ -813,11 +895,11 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
813
895
|
if (theEvent) {
|
|
814
896
|
// Check if the request being added back is for a sync event in which case mark it no longer a sync event
|
|
815
897
|
if (theEvent.sync) {
|
|
816
|
-
theEvent.latency =
|
|
898
|
+
theEvent.latency = EventLatencyValue.Immediate;
|
|
817
899
|
theEvent.sync = false;
|
|
818
900
|
}
|
|
819
901
|
|
|
820
|
-
if (theEvent.sendAttempt <
|
|
902
|
+
if (theEvent.sendAttempt < maxSendAttempts) {
|
|
821
903
|
// Reset the event timings
|
|
822
904
|
setProcessTelemetryTimings(theEvent, _self.identifier);
|
|
823
905
|
_addEventToQueues(theEvent, false);
|
|
@@ -846,8 +928,9 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
846
928
|
try {
|
|
847
929
|
notifyFunc.apply(manager, theArgs);
|
|
848
930
|
} catch (e) {
|
|
849
|
-
_self.diagLog()
|
|
850
|
-
|
|
931
|
+
_throwInternal(_self.diagLog(),
|
|
932
|
+
eLoggingSeverity.CRITICAL,
|
|
933
|
+
_eInternalMessageId.NotificationException,
|
|
851
934
|
evtName + " notification failed: " + e);
|
|
852
935
|
}
|
|
853
936
|
}
|
|
@@ -959,13 +1042,6 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
|
|
|
959
1042
|
// @DynamicProtoStub - DO NOT add any code as this will be removed during packaging
|
|
960
1043
|
}
|
|
961
1044
|
|
|
962
|
-
/**
|
|
963
|
-
* Batch all current events in the queues and send them.
|
|
964
|
-
*/
|
|
965
|
-
public teardown() {
|
|
966
|
-
// @DynamicProtoStub - DO NOT add any code as this will be removed during packaging
|
|
967
|
-
}
|
|
968
|
-
|
|
969
1045
|
/**
|
|
970
1046
|
* Pause the transmission of any requests
|
|
971
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
|
}
|