@microsoft/1ds-post-js 3.1.11 → 3.2.2

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