@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.
Files changed (57) hide show
  1. package/README.md +124 -6
  2. package/bundle/{ms.post-3.1.10.gbl.js → ms.post-3.2.1.gbl.js} +1502 -725
  3. package/bundle/ms.post-3.2.1.gbl.js.map +1 -0
  4. package/bundle/ms.post-3.2.1.gbl.min.js +7 -0
  5. package/bundle/ms.post-3.2.1.gbl.min.js.map +1 -0
  6. package/bundle/ms.post-3.2.1.integrity.json +46 -0
  7. package/bundle/{ms.post-3.1.10.js → ms.post-3.2.1.js} +1502 -725
  8. package/bundle/ms.post-3.2.1.js.map +1 -0
  9. package/bundle/ms.post-3.2.1.min.js +7 -0
  10. package/bundle/ms.post-3.2.1.min.js.map +1 -0
  11. package/bundle/ms.post.gbl.js +1501 -724
  12. package/bundle/ms.post.gbl.js.map +1 -1
  13. package/bundle/ms.post.gbl.min.js +2 -2
  14. package/bundle/ms.post.gbl.min.js.map +1 -1
  15. package/bundle/ms.post.integrity.json +17 -17
  16. package/bundle/ms.post.js +1501 -724
  17. package/bundle/ms.post.js.map +1 -1
  18. package/bundle/ms.post.min.js +2 -2
  19. package/bundle/ms.post.min.js.map +1 -1
  20. package/dist/ms.post.js +264 -149
  21. package/dist/ms.post.js.map +1 -1
  22. package/dist/ms.post.min.js +2 -2
  23. package/dist/ms.post.min.js.map +1 -1
  24. package/dist-esm/src/BatchNotificationActions.js +1 -1
  25. package/dist-esm/src/ClockSkewManager.js +1 -1
  26. package/dist-esm/src/Constants.d.ts +1 -0
  27. package/dist-esm/src/Constants.js +2 -1
  28. package/dist-esm/src/Constants.js.map +1 -1
  29. package/dist-esm/src/DataModels.d.ts +49 -0
  30. package/dist-esm/src/DataModels.js +1 -1
  31. package/dist-esm/src/EventBatch.js +1 -1
  32. package/dist-esm/src/HttpManager.d.ts +1 -1
  33. package/dist-esm/src/HttpManager.js +102 -58
  34. package/dist-esm/src/HttpManager.js.map +1 -1
  35. package/dist-esm/src/Index.js +1 -1
  36. package/dist-esm/src/KillSwitch.js +1 -1
  37. package/dist-esm/src/PostChannel.d.ts +0 -4
  38. package/dist-esm/src/PostChannel.js +171 -104
  39. package/dist-esm/src/PostChannel.js.map +1 -1
  40. package/dist-esm/src/RetryPolicy.d.ts +20 -25
  41. package/dist-esm/src/RetryPolicy.js +35 -44
  42. package/dist-esm/src/RetryPolicy.js.map +1 -1
  43. package/dist-esm/src/Serializer.js +1 -1
  44. package/dist-esm/src/typings/XDomainRequest.js +1 -1
  45. package/package.json +2 -2
  46. package/src/Constants.ts +1 -0
  47. package/src/DataModels.ts +62 -1
  48. package/src/HttpManager.ts +110 -69
  49. package/src/PostChannel.ts +203 -127
  50. package/src/RetryPolicy.ts +33 -38
  51. package/bundle/ms.post-3.1.10.gbl.js.map +0 -1
  52. package/bundle/ms.post-3.1.10.gbl.min.js +0 -7
  53. package/bundle/ms.post-3.1.10.gbl.min.js.map +0 -1
  54. package/bundle/ms.post-3.1.10.integrity.json +0 -46
  55. package/bundle/ms.post-3.1.10.js.map +0 -1
  56. package/bundle/ms.post-3.1.10.min.js +0 -7
  57. package/bundle/ms.post-3.1.10.min.js.map +0 -1
@@ -5,10 +5,15 @@
5
5
  */
6
6
  import {
7
7
  BaseTelemetryPlugin, IChannelControls, IExtendedConfiguration, IExtendedAppInsightsCore,
8
- EventLatency, NotificationManager, EventsDiscardedReason, IPlugin, ITelemetryItem,
9
- IAppInsightsCore, isValueAssigned, addPageUnloadEventListener, addPageHideEventListener, addPageShowEventListener, setProcessTelemetryTimings,
10
- isWindowObjectAvailable, IProcessTelemetryContext, SendRequestReason, arrForEach,
11
- LoggingSeverity, _ExtendedInternalMessageId, doPerf, objForEachKey, optimizeObject, isChromium, getWindow, EventSendType, addEventHandler, getDocument,
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 RetryPolicy from "./RetryPolicy";
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 MaxRetries = 1;
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
- _initializeProfiles();
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
- _self.setInitialized(false);
114
- let ctx = _self._getTelCtx();
115
- coreConfig.extensionConfig[_self.identifier] = coreConfig.extensionConfig[_self.identifier] || {};
116
- _config = ctx.getExtCfg(_self.identifier);
117
- _self._setTimeoutOverride = _config.setTimeoutOverride ? _config.setTimeoutOverride : setTimeout.bind(globalContext);
118
- _self._clearTimeoutOverride = _config.clearTimeoutOverride ? _config.clearTimeoutOverride : clearTimeout.bind(globalContext);
119
-
120
- // Only try and use the optimizeObject() if this appears to be a chromium based browser and it has not been explicitly disabled
121
- _optimizeObject = !_config.disableOptimizeObj && isChromium();
122
-
123
- var existingGetWParamMethod = extendedCore.getWParam;
124
- extendedCore.getWParam = () => {
125
- var wparam = 0;
126
- if (_config.ignoreMc1Ms0CookieProcessing) {
127
- wparam = wparam | 2;
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
- return wparam | existingGetWParamMethod();
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
- _releaseAllQueues(EventSendType.SendBeacon, SendRequestReason.Unload);
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 = EventLatency.Normal;
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 = EventLatency.RealTime;
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 === EventLatency.Immediate) {
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 = EventLatency.Normal;
329
+ let dropLatency = EventLatencyValue.Normal;
291
330
  let dropNumber = EventsDroppedAtOneTime;
292
- if (evtLatency === EventLatency.Immediate) {
331
+ if (evtLatency === EventLatencyValue.Immediate) {
293
332
  // Only drop other immediate events as they are not technically sharing the general queue
294
- dropLatency = EventLatency.Immediate;
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 = EventLatency.Normal; !doFlush && latency <= EventLatency.RealTime; 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(EventLatency.Normal, EventSendType.Batched, sendReason);
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(EventLatency.Normal, EventSendType.Synchronous, sendReason);
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(EventLatency.Immediate, EventSendType.Batched, SendRequestReason.NormalSchedule);
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 ? EventLatency.RealTime : EventLatency.Normal, EventSendType.Batched, SendRequestReason.NormalSchedule);
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 = RetryPolicy.getMillisToBackoffForRetry(_currentBackoffCount - 1);
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(EventLatency.Normal, sendType, sendReason);
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[EventLatency.Immediate] = {
636
+ _batchQueues[EventLatencyValue.Immediate] = {
560
637
  batches: [],
561
638
  iKeyMap: {}
562
639
  };
563
- _batchQueues[EventLatency.RealTime] = {
640
+ _batchQueues[EventLatencyValue.RealTime] = {
564
641
  batches: [],
565
642
  iKeyMap: {}
566
643
  };
567
- _batchQueues[EventLatency.CostDeferred] = {
644
+ _batchQueues[EventLatencyValue.CostDeferred] = {
568
645
  batches: [],
569
646
  iKeyMap: {}
570
647
  };
571
- _batchQueues[EventLatency.Normal] = {
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 = EventLatency.Normal;
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 !== EventLatency.Immediate) {
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 === EventLatency.Immediate) {
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 = EventLatency.Normal; latency <= EventLatency.Immediate; 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 === EventLatency.Immediate) {
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 = EventLatency.Immediate;
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 === EventLatency.Immediate) {
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(EventLatency.Normal, EventSendType.Batched, sendReason);
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 = EventLatency.Immediate;
898
+ theEvent.latency = EventLatencyValue.Immediate;
817
899
  theEvent.sync = false;
818
900
  }
819
901
 
820
- if (theEvent.sendAttempt < MaxSendAttempts) {
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().throwInternal(LoggingSeverity.CRITICAL,
850
- _ExtendedInternalMessageId.NotificationException,
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
  */
@@ -9,43 +9,38 @@ const BaseBackoff = 3000;
9
9
  const MaxBackoff = 600000;
10
10
 
11
11
  /**
12
- * Class for retry policy.
13
- */
14
- export default class RetryPolicy {
15
- /**
16
- * Determine if the request should be retried for the given status code.
17
- * The below expression reads that we should only retry for:
18
- * - HttpStatusCodes that are smaller than 300.
19
- * - HttpStatusCodes greater or equal to 500 (except for 501-NotImplement
20
- * and 505-HttpVersionNotSupport).
21
- * - HttpStatusCode 408-RequestTimeout.
22
- * - HttpStatusCode 429.
23
- * This is based on Microsoft.WindowsAzure.Storage.RetryPolicies.ExponentialRetry class
24
- * @param httpStatusCode - The status code returned for the request.
25
- * @returns True if request should be retried, false otherwise.
26
- */
27
- public static shouldRetryForStatus(httpStatusCode: number): boolean {
28
- /* tslint:disable:triple-equals */
29
- // Disabling triple-equals rule to avoid httpOverrides from failing because they are returning a string value
30
- return !((httpStatusCode >= 300 && httpStatusCode < 500 && httpStatusCode != 408 && httpStatusCode != 429)
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
- * Gets the number of milliseconds to back off before retrying the request. The
38
- * back off duration is exponentially scaled based on the number of retries already
39
- * done for the request.
40
- * @param retriesSoFar - The number of times the request has already been retried.
41
- * @returns The back off duration for the request before it can be retried.
42
- */
43
- public static getMillisToBackoffForRetry(retriesSoFar: number): number {
44
- let waitDuration = 0;
45
- let minBackoff = BaseBackoff * RandomizationLowerThreshold;
46
- let maxBackoff = BaseBackoff * RandomizationUpperThreshold;
47
- let randomBackoff = Math.floor(Math.random() * (maxBackoff - minBackoff)) + minBackoff;
48
- waitDuration = Math.pow(2, retriesSoFar) * randomBackoff;
49
- return Math.min(waitDuration, MaxBackoff);
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
  }