@splitsoftware/splitio-commons 1.5.1-rc.0 → 1.5.1-rc.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/CHANGES.txt +1 -2
- package/cjs/integrations/ga/GaToSplit.js +11 -12
- package/cjs/services/splitApi.js +4 -4
- package/cjs/sync/polling/fetchers/segmentChangesFetcher.js +5 -5
- package/cjs/sync/polling/fetchers/splitChangesFetcher.js +2 -2
- package/cjs/sync/polling/updaters/segmentChangesUpdater.js +34 -34
- package/cjs/sync/polling/updaters/splitChangesUpdater.js +4 -3
- package/cjs/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +46 -46
- package/cjs/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.js +82 -64
- package/cjs/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +74 -58
- package/cjs/sync/streaming/UpdateWorkers/constants.js +6 -0
- package/cjs/sync/streaming/pushManager.js +6 -7
- package/cjs/sync/syncTask.js +13 -16
- package/cjs/utils/Backoff.js +3 -2
- package/esm/integrations/ga/GaToSplit.js +11 -12
- package/esm/services/splitApi.js +4 -4
- package/esm/sync/polling/fetchers/segmentChangesFetcher.js +5 -5
- package/esm/sync/polling/fetchers/splitChangesFetcher.js +2 -2
- package/esm/sync/polling/updaters/segmentChangesUpdater.js +34 -34
- package/esm/sync/polling/updaters/splitChangesUpdater.js +4 -3
- package/esm/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +46 -47
- package/esm/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.js +82 -65
- package/esm/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +74 -59
- package/esm/sync/streaming/UpdateWorkers/constants.js +3 -0
- package/esm/sync/streaming/pushManager.js +6 -7
- package/esm/sync/syncTask.js +13 -16
- package/esm/utils/Backoff.js +3 -2
- package/package.json +1 -1
- package/src/integrations/ga/GaToSplit.ts +8 -14
- package/src/integrations/ga/types.ts +2 -13
- package/src/services/splitApi.ts +4 -4
- package/src/services/types.ts +2 -2
- package/src/sync/polling/fetchers/segmentChangesFetcher.ts +5 -4
- package/src/sync/polling/fetchers/splitChangesFetcher.ts +2 -1
- package/src/sync/polling/fetchers/types.ts +2 -0
- package/src/sync/polling/pollingManagerCS.ts +5 -5
- package/src/sync/polling/syncTasks/mySegmentsSyncTask.ts +2 -2
- package/src/sync/polling/types.ts +14 -6
- package/src/sync/polling/updaters/mySegmentsUpdater.ts +4 -4
- package/src/sync/polling/updaters/segmentChangesUpdater.ts +34 -32
- package/src/sync/polling/updaters/splitChangesUpdater.ts +5 -4
- package/src/sync/streaming/SSEHandler/types.ts +0 -7
- package/src/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.ts +45 -54
- package/src/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.ts +78 -63
- package/src/sync/streaming/UpdateWorkers/SplitsUpdateWorker.ts +73 -61
- package/src/sync/streaming/UpdateWorkers/constants.ts +3 -0
- package/src/sync/streaming/UpdateWorkers/types.ts +2 -4
- package/src/sync/streaming/pushManager.ts +12 -12
- package/src/sync/streaming/types.ts +2 -2
- package/src/sync/syncTask.ts +16 -18
- package/src/utils/Backoff.ts +7 -2
- package/types/integrations/ga/types.d.ts +2 -13
- package/types/services/types.d.ts +2 -2
- package/types/sync/polling/fetchers/types.d.ts +2 -2
- package/types/sync/polling/syncTasks/mySegmentsSyncTask.d.ts +2 -2
- package/types/sync/polling/types.d.ts +11 -6
- package/types/sync/polling/updaters/segmentChangesUpdater.d.ts +1 -1
- package/types/sync/polling/updaters/splitChangesUpdater.d.ts +1 -1
- package/types/sync/streaming/SSEHandler/types.d.ts +0 -4
- package/types/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.d.ts +3 -24
- package/types/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.d.ts +3 -23
- package/types/sync/streaming/UpdateWorkers/SplitsUpdateWorker.d.ts +6 -33
- package/types/sync/streaming/UpdateWorkers/types.d.ts +1 -2
- package/types/sync/streaming/types.d.ts +2 -2
- package/types/sync/syncTask.d.ts +2 -3
- package/types/utils/Backoff.d.ts +2 -0
- package/src/integrations/ga/autoRequire.js +0 -33
package/CHANGES.txt
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
1.
|
|
2
|
-
- Added `autoRequire` configuration option to the Google Analytics to Split integration (See https://help.split.io/hc/en-us/articles/360040838752#set-up-with-gtm-and-gtag.js).
|
|
1
|
+
1.5.1 (July XX, 2022)
|
|
3
2
|
- Updated browser listener to push remaining impressions and events on 'visibilitychange' and 'pagehide' DOM events, instead of 'unload', which is not reliable in mobile and modern Web browsers (See https://developer.chrome.com/blog/page-lifecycle-api/#legacy-lifecycle-apis-to-avoid).
|
|
4
3
|
|
|
5
4
|
1.5.0 (June 29, 2022)
|
|
@@ -10,24 +10,23 @@ var logNameMapper = 'ga-to-split:mapper';
|
|
|
10
10
|
/**
|
|
11
11
|
* Provides a plugin to use with analytics.js, accounting for the possibility
|
|
12
12
|
* that the global command queue has been renamed or not yet defined.
|
|
13
|
-
* @param
|
|
14
|
-
* @param
|
|
15
|
-
* @param pluginConstructor The plugin constructor function.
|
|
16
|
-
* @param log Logger instance.
|
|
17
|
-
* @param autoRequire If true, log error when auto-require script is not detected
|
|
13
|
+
* @param {string} pluginName The plugin name identifier.
|
|
14
|
+
* @param {Function} pluginConstructor The plugin constructor function.
|
|
18
15
|
*/
|
|
19
|
-
function providePlugin(
|
|
16
|
+
function providePlugin(pluginName, pluginConstructor) {
|
|
20
17
|
// get reference to global command queue. Init it if not defined yet.
|
|
18
|
+
// @ts-expect-error
|
|
21
19
|
var gaAlias = window.GoogleAnalyticsObject || 'ga';
|
|
22
20
|
window[gaAlias] = window[gaAlias] || function () {
|
|
23
|
-
|
|
21
|
+
var args = [];
|
|
22
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
23
|
+
args[_i] = arguments[_i];
|
|
24
|
+
}
|
|
25
|
+
(window[gaAlias].q = window[gaAlias].q || []).push(args);
|
|
24
26
|
};
|
|
25
27
|
// provides the plugin for use with analytics.js.
|
|
28
|
+
// @ts-expect-error
|
|
26
29
|
window[gaAlias]('provide', pluginName, pluginConstructor);
|
|
27
|
-
if (autoRequire && (!window[gaAlias].q || window[gaAlias].q.push === [].push)) {
|
|
28
|
-
// Expecting spy on ga.q push method but not found
|
|
29
|
-
log.error(logPrefix + 'integration is configured to autorequire the splitTracker plugin, but the necessary script does not seem to have run.');
|
|
30
|
-
}
|
|
31
30
|
}
|
|
32
31
|
// Default mapping: object used for building the default mapper from hits to Split events
|
|
33
32
|
var defaultMapping = {
|
|
@@ -247,6 +246,6 @@ function GaToSplit(sdkOptions, params) {
|
|
|
247
246
|
return SplitTracker;
|
|
248
247
|
}());
|
|
249
248
|
// Register the plugin, even if config is invalid, since, if not provided, it will block `ga` command queue.
|
|
250
|
-
providePlugin(
|
|
249
|
+
providePlugin('splitTracker', SplitTracker);
|
|
251
250
|
}
|
|
252
251
|
exports.GaToSplit = GaToSplit;
|
package/cjs/services/splitApi.js
CHANGED
|
@@ -37,12 +37,12 @@ function splitApiFactory(settings, platform, telemetryTracker) {
|
|
|
37
37
|
}
|
|
38
38
|
return splitHttpClient(url, undefined, telemetryTracker.trackHttp(constants_1.TOKEN));
|
|
39
39
|
},
|
|
40
|
-
fetchSplitChanges: function (since, noCache) {
|
|
41
|
-
var url = urls.sdk + "/splitChanges?since=" + since + (filterQueryString || '');
|
|
40
|
+
fetchSplitChanges: function (since, noCache, till) {
|
|
41
|
+
var url = urls.sdk + "/splitChanges?since=" + since + (till ? '&till=' + till : '') + (filterQueryString || '');
|
|
42
42
|
return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined, telemetryTracker.trackHttp(constants_1.SPLITS));
|
|
43
43
|
},
|
|
44
|
-
fetchSegmentChanges: function (since, segmentName, noCache) {
|
|
45
|
-
var url = urls.sdk + "/segmentChanges/" + segmentName + "?since=" + since;
|
|
44
|
+
fetchSegmentChanges: function (since, segmentName, noCache, till) {
|
|
45
|
+
var url = urls.sdk + "/segmentChanges/" + segmentName + "?since=" + since + (till ? '&till=' + till : '');
|
|
46
46
|
return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined, telemetryTracker.trackHttp(constants_1.SEGMENT));
|
|
47
47
|
},
|
|
48
48
|
fetchMySegments: function (userMatchingKey, noCache) {
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.segmentChangesFetcherFactory = void 0;
|
|
4
4
|
var tslib_1 = require("tslib");
|
|
5
|
-
function greedyFetch(fetchSegmentChanges, since, segmentName, noCache) {
|
|
6
|
-
return fetchSegmentChanges(since, segmentName, noCache)
|
|
5
|
+
function greedyFetch(fetchSegmentChanges, since, segmentName, noCache, targetTill) {
|
|
6
|
+
return fetchSegmentChanges(since, segmentName, noCache, targetTill)
|
|
7
7
|
.then(function (resp) { return resp.json(); })
|
|
8
8
|
.then(function (json) {
|
|
9
9
|
var since = json.since, till = json.till;
|
|
@@ -11,7 +11,7 @@ function greedyFetch(fetchSegmentChanges, since, segmentName, noCache) {
|
|
|
11
11
|
return [json];
|
|
12
12
|
}
|
|
13
13
|
else {
|
|
14
|
-
return Promise.all([json, greedyFetch(fetchSegmentChanges, till, segmentName, noCache)]).then(function (flatMe) {
|
|
14
|
+
return Promise.all([json, greedyFetch(fetchSegmentChanges, till, segmentName, noCache, targetTill)]).then(function (flatMe) {
|
|
15
15
|
return (0, tslib_1.__spreadArray)([flatMe[0]], flatMe[1], true);
|
|
16
16
|
});
|
|
17
17
|
}
|
|
@@ -22,10 +22,10 @@ function greedyFetch(fetchSegmentChanges, since, segmentName, noCache) {
|
|
|
22
22
|
* SegmentChanges fetcher is a wrapper around `segmentChanges` API service that parses the response and handle errors and retries.
|
|
23
23
|
*/
|
|
24
24
|
function segmentChangesFetcherFactory(fetchSegmentChanges) {
|
|
25
|
-
return function segmentChangesFetcher(since, segmentName, noCache,
|
|
25
|
+
return function segmentChangesFetcher(since, segmentName, noCache, till,
|
|
26
26
|
// Optional decorator for `fetchMySegments` promise, such as timeout or time tracker
|
|
27
27
|
decorator) {
|
|
28
|
-
var segmentsPromise = greedyFetch(fetchSegmentChanges, since, segmentName, noCache);
|
|
28
|
+
var segmentsPromise = greedyFetch(fetchSegmentChanges, since, segmentName, noCache, till);
|
|
29
29
|
if (decorator)
|
|
30
30
|
segmentsPromise = decorator(segmentsPromise);
|
|
31
31
|
return segmentsPromise;
|
|
@@ -6,10 +6,10 @@ exports.splitChangesFetcherFactory = void 0;
|
|
|
6
6
|
* SplitChanges fetcher is a wrapper around `splitChanges` API service that parses the response and handle errors.
|
|
7
7
|
*/
|
|
8
8
|
function splitChangesFetcherFactory(fetchSplitChanges) {
|
|
9
|
-
return function splitChangesFetcher(since, noCache,
|
|
9
|
+
return function splitChangesFetcher(since, noCache, till,
|
|
10
10
|
// Optional decorator for `fetchSplitChanges` promise, such as timeout or time tracker
|
|
11
11
|
decorator) {
|
|
12
|
-
var splitsPromise = fetchSplitChanges(since, noCache);
|
|
12
|
+
var splitsPromise = fetchSplitChanges(since, noCache, till);
|
|
13
13
|
if (decorator)
|
|
14
14
|
splitsPromise = decorator(splitsPromise);
|
|
15
15
|
return splitsPromise.then(function (resp) { return resp.json(); });
|
|
@@ -18,54 +18,54 @@ var thenable_1 = require("../../../utils/promise/thenable");
|
|
|
18
18
|
*/
|
|
19
19
|
function segmentChangesUpdaterFactory(log, segmentChangesFetcher, segments, readiness) {
|
|
20
20
|
var readyOnAlreadyExistentState = true;
|
|
21
|
+
function updateSegment(segmentName, noCache, till, fetchOnlyNew) {
|
|
22
|
+
log.debug(constants_2.LOG_PREFIX_SYNC_SEGMENTS + "Processing segment " + segmentName);
|
|
23
|
+
var sincePromise = Promise.resolve(segments.getChangeNumber(segmentName));
|
|
24
|
+
return sincePromise.then(function (since) {
|
|
25
|
+
// if fetchOnlyNew flag, avoid processing already fetched segments
|
|
26
|
+
if (fetchOnlyNew && since !== -1)
|
|
27
|
+
return -1;
|
|
28
|
+
return segmentChangesFetcher(since, segmentName, noCache, till).then(function (changes) {
|
|
29
|
+
var changeNumber = -1;
|
|
30
|
+
var results = [];
|
|
31
|
+
changes.forEach(function (x) {
|
|
32
|
+
if (x.added.length > 0)
|
|
33
|
+
results.push(segments.addToSegment(segmentName, x.added));
|
|
34
|
+
if (x.removed.length > 0)
|
|
35
|
+
results.push(segments.removeFromSegment(segmentName, x.removed));
|
|
36
|
+
if (x.added.length > 0 || x.removed.length > 0) {
|
|
37
|
+
results.push(segments.setChangeNumber(segmentName, x.till));
|
|
38
|
+
changeNumber = x.till;
|
|
39
|
+
}
|
|
40
|
+
log.debug(constants_2.LOG_PREFIX_SYNC_SEGMENTS + "Processed " + segmentName + " with till = " + x.till + ". Added: " + x.added.length + ". Removed: " + x.removed.length);
|
|
41
|
+
});
|
|
42
|
+
// If at least one storage operation result is a promise, join all in a single promise.
|
|
43
|
+
if (results.some(function (result) { return (0, thenable_1.thenable)(result); }))
|
|
44
|
+
return Promise.all(results).then(function () { return changeNumber; });
|
|
45
|
+
return changeNumber;
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
}
|
|
21
49
|
/**
|
|
22
50
|
* Segments updater returns a promise that resolves with a `false` boolean value if it fails at least to fetch a segment or synchronize it with the storage.
|
|
23
51
|
* Thus, a false result doesn't imply that SDK_SEGMENTS_ARRIVED was not emitted.
|
|
24
52
|
* Returned promise will not be rejected.
|
|
25
53
|
*
|
|
26
|
-
* @param {string[] | undefined} segmentNames list of segment names to fetch. By passing `undefined` it fetches the list of segments registered at the storage
|
|
27
|
-
* @param {boolean | undefined} noCache true to revalidate data to fetch on a SEGMENT_UPDATE notifications.
|
|
28
54
|
* @param {boolean | undefined} fetchOnlyNew if true, only fetch the segments that not exists, i.e., which `changeNumber` is equal to -1.
|
|
29
55
|
* This param is used by SplitUpdateWorker on server-side SDK, to fetch new registered segments on SPLIT_UPDATE notifications.
|
|
56
|
+
* @param {string | undefined} segmentName segment name to fetch. By passing `undefined` it fetches the list of segments registered at the storage
|
|
57
|
+
* @param {boolean | undefined} noCache true to revalidate data to fetch on a SEGMENT_UPDATE notifications.
|
|
58
|
+
* @param {number | undefined} till till target for the provided segmentName, for CDN bypass.
|
|
30
59
|
*/
|
|
31
|
-
return function segmentChangesUpdater(
|
|
60
|
+
return function segmentChangesUpdater(fetchOnlyNew, segmentName, noCache, till) {
|
|
32
61
|
log.debug(constants_2.LOG_PREFIX_SYNC_SEGMENTS + "Started segments update");
|
|
33
62
|
// If not a segment name provided, read list of available segments names to be updated.
|
|
34
|
-
var segmentsPromise = Promise.resolve(
|
|
63
|
+
var segmentsPromise = Promise.resolve(segmentName ? [segmentName] : segments.getRegisteredSegments());
|
|
35
64
|
return segmentsPromise.then(function (segmentNames) {
|
|
36
65
|
// Async fetchers are collected here.
|
|
37
66
|
var updaters = [];
|
|
38
|
-
var _loop_1 = function (index) {
|
|
39
|
-
var segmentName = segmentNames[index];
|
|
40
|
-
log.debug(constants_2.LOG_PREFIX_SYNC_SEGMENTS + "Processing segment " + segmentName);
|
|
41
|
-
var sincePromise = Promise.resolve(segments.getChangeNumber(segmentName));
|
|
42
|
-
updaters.push(sincePromise.then(function (since) {
|
|
43
|
-
// if fetchOnlyNew flag, avoid processing already fetched segments
|
|
44
|
-
if (fetchOnlyNew && since !== -1)
|
|
45
|
-
return -1;
|
|
46
|
-
return segmentChangesFetcher(since, segmentName, noCache).then(function (changes) {
|
|
47
|
-
var changeNumber = -1;
|
|
48
|
-
var results = [];
|
|
49
|
-
changes.forEach(function (x) {
|
|
50
|
-
if (x.added.length > 0)
|
|
51
|
-
results.push(segments.addToSegment(segmentName, x.added));
|
|
52
|
-
if (x.removed.length > 0)
|
|
53
|
-
results.push(segments.removeFromSegment(segmentName, x.removed));
|
|
54
|
-
if (x.added.length > 0 || x.removed.length > 0) {
|
|
55
|
-
results.push(segments.setChangeNumber(segmentName, x.till));
|
|
56
|
-
changeNumber = x.till;
|
|
57
|
-
}
|
|
58
|
-
log.debug(constants_2.LOG_PREFIX_SYNC_SEGMENTS + "Processed " + segmentName + " with till = " + x.till + ". Added: " + x.added.length + ". Removed: " + x.removed.length);
|
|
59
|
-
});
|
|
60
|
-
// If at least one storage operation result is a promise, join all in a single promise.
|
|
61
|
-
if (results.some(function (result) { return (0, thenable_1.thenable)(result); }))
|
|
62
|
-
return Promise.all(results).then(function () { return changeNumber; });
|
|
63
|
-
return changeNumber;
|
|
64
|
-
});
|
|
65
|
-
}));
|
|
66
|
-
};
|
|
67
67
|
for (var index = 0; index < segmentNames.length; index++) {
|
|
68
|
-
|
|
68
|
+
updaters.push(updateSegment(segmentNames[index], noCache, till, fetchOnlyNew));
|
|
69
69
|
}
|
|
70
70
|
return Promise.all(updaters).then(function (shouldUpdateFlags) {
|
|
71
71
|
// if at least one segment fetch succeeded, mark segments ready
|
|
@@ -84,16 +84,17 @@ function splitChangesUpdaterFactory(log, splitChangesFetcher, splits, segments,
|
|
|
84
84
|
* Returned promise will not be rejected.
|
|
85
85
|
*
|
|
86
86
|
* @param {boolean | undefined} noCache true to revalidate data to fetch
|
|
87
|
+
* @param {boolean | undefined} till query param to bypass CDN requests
|
|
87
88
|
*/
|
|
88
|
-
return function splitChangesUpdater(noCache) {
|
|
89
|
+
return function splitChangesUpdater(noCache, till) {
|
|
89
90
|
/**
|
|
90
91
|
* @param {number} since current changeNumber at splitsCache
|
|
91
|
-
* @param {number} retry current number of retry
|
|
92
|
+
* @param {number} retry current number of retry attempts
|
|
92
93
|
*/
|
|
93
94
|
function _splitChangesUpdater(since, retry) {
|
|
94
95
|
if (retry === void 0) { retry = 0; }
|
|
95
96
|
log.debug(constants_2.SYNC_SPLITS_FETCH, [since]);
|
|
96
|
-
var fetcherPromise = splitChangesFetcher(since, noCache, _promiseDecorator)
|
|
97
|
+
var fetcherPromise = splitChangesFetcher(since, noCache, till, _promiseDecorator)
|
|
97
98
|
.then(function (splitChanges) {
|
|
98
99
|
startingUp = false;
|
|
99
100
|
var mutation = computeSplitsMutation(splitChanges.splits);
|
|
@@ -3,59 +3,59 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.MySegmentsUpdateWorker = void 0;
|
|
4
4
|
var Backoff_1 = require("../../../utils/Backoff");
|
|
5
5
|
/**
|
|
6
|
-
* MySegmentsUpdateWorker
|
|
6
|
+
* MySegmentsUpdateWorker factory
|
|
7
7
|
*/
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
this.backoff = new Backoff_1.Backoff(this.__handleMySegmentsUpdateCall);
|
|
21
|
-
}
|
|
22
|
-
// Private method
|
|
23
|
-
// Precondition: this.mySegmentsSyncTask.isSynchronizingMySegments === false
|
|
24
|
-
MySegmentsUpdateWorker.prototype.__handleMySegmentsUpdateCall = function () {
|
|
25
|
-
var _this = this;
|
|
26
|
-
if (this.maxChangeNumber > this.currentChangeNumber) {
|
|
27
|
-
this.handleNewEvent = false;
|
|
28
|
-
var currentMaxChangeNumber_1 = this.maxChangeNumber;
|
|
8
|
+
function MySegmentsUpdateWorker(mySegmentsSyncTask) {
|
|
9
|
+
var maxChangeNumber = 0; // keeps the maximum changeNumber among queued events
|
|
10
|
+
var currentChangeNumber = -1;
|
|
11
|
+
var handleNewEvent = false;
|
|
12
|
+
var isHandlingEvent;
|
|
13
|
+
var _segmentsData; // keeps the segmentsData (if included in notification payload) from the queued event with maximum changeNumber
|
|
14
|
+
var backoff = new Backoff_1.Backoff(__handleMySegmentsUpdateCall);
|
|
15
|
+
function __handleMySegmentsUpdateCall() {
|
|
16
|
+
isHandlingEvent = true;
|
|
17
|
+
if (maxChangeNumber > currentChangeNumber) {
|
|
18
|
+
handleNewEvent = false;
|
|
19
|
+
var currentMaxChangeNumber_1 = maxChangeNumber;
|
|
29
20
|
// fetch mySegments revalidating data if cached
|
|
30
|
-
|
|
21
|
+
mySegmentsSyncTask.execute(_segmentsData, true).then(function (result) {
|
|
22
|
+
if (!isHandlingEvent)
|
|
23
|
+
return; // halt if `stop` has been called
|
|
31
24
|
if (result !== false) // Unlike `Splits|SegmentsUpdateWorker`, we cannot use `mySegmentsCache.getChangeNumber` since `/mySegments` endpoint doesn't provide this value.
|
|
32
|
-
|
|
33
|
-
if (
|
|
34
|
-
|
|
25
|
+
currentChangeNumber = Math.max(currentChangeNumber, currentMaxChangeNumber_1); // use `currentMaxChangeNumber`, in case that `maxChangeNumber` was updated during fetch.
|
|
26
|
+
if (handleNewEvent) {
|
|
27
|
+
__handleMySegmentsUpdateCall();
|
|
35
28
|
}
|
|
36
29
|
else {
|
|
37
|
-
|
|
30
|
+
backoff.scheduleCall();
|
|
38
31
|
}
|
|
39
32
|
});
|
|
40
33
|
}
|
|
34
|
+
else {
|
|
35
|
+
isHandlingEvent = false;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
/**
|
|
40
|
+
* Invoked by NotificationProcessor on MY_SEGMENTS_UPDATE event
|
|
41
|
+
*
|
|
42
|
+
* @param {number} changeNumber change number of the MY_SEGMENTS_UPDATE notification
|
|
43
|
+
* @param {SegmentsData | undefined} segmentsData might be undefined
|
|
44
|
+
*/
|
|
45
|
+
put: function (changeNumber, segmentsData) {
|
|
46
|
+
if (changeNumber <= currentChangeNumber || changeNumber <= maxChangeNumber)
|
|
47
|
+
return;
|
|
48
|
+
maxChangeNumber = changeNumber;
|
|
49
|
+
handleNewEvent = true;
|
|
50
|
+
_segmentsData = segmentsData;
|
|
51
|
+
if (backoff.timeoutID || !isHandlingEvent)
|
|
52
|
+
__handleMySegmentsUpdateCall();
|
|
53
|
+
backoff.reset();
|
|
54
|
+
},
|
|
55
|
+
stop: function () {
|
|
56
|
+
isHandlingEvent = false;
|
|
57
|
+
backoff.reset();
|
|
58
|
+
}
|
|
41
59
|
};
|
|
42
|
-
|
|
43
|
-
* Invoked by NotificationProcessor on MY_SEGMENTS_UPDATE event
|
|
44
|
-
*
|
|
45
|
-
* @param {number} changeNumber change number of the MY_SEGMENTS_UPDATE notification
|
|
46
|
-
* @param {SegmentsData | undefined} segmentsData might be undefined
|
|
47
|
-
*/
|
|
48
|
-
MySegmentsUpdateWorker.prototype.put = function (changeNumber, segmentsData) {
|
|
49
|
-
if (changeNumber <= this.currentChangeNumber || changeNumber <= this.maxChangeNumber)
|
|
50
|
-
return;
|
|
51
|
-
this.maxChangeNumber = changeNumber;
|
|
52
|
-
this.handleNewEvent = true;
|
|
53
|
-
this.backoff.reset();
|
|
54
|
-
this.segmentsData = segmentsData;
|
|
55
|
-
if (this.mySegmentsSyncTask.isExecuting())
|
|
56
|
-
return;
|
|
57
|
-
this.__handleMySegmentsUpdateCall();
|
|
58
|
-
};
|
|
59
|
-
return MySegmentsUpdateWorker;
|
|
60
|
-
}());
|
|
60
|
+
}
|
|
61
61
|
exports.MySegmentsUpdateWorker = MySegmentsUpdateWorker;
|
|
@@ -2,73 +2,91 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.SegmentsUpdateWorker = void 0;
|
|
4
4
|
var Backoff_1 = require("../../../utils/Backoff");
|
|
5
|
+
var constants_1 = require("./constants");
|
|
5
6
|
/**
|
|
6
|
-
*
|
|
7
|
+
* SegmentsUpdateWorker factory
|
|
7
8
|
*/
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
9
|
+
function SegmentsUpdateWorker(log, segmentsSyncTask, segmentsCache) {
|
|
10
|
+
// Handles retries with CDN bypass per segment name
|
|
11
|
+
function SegmentUpdateWorker(segment) {
|
|
12
|
+
var maxChangeNumber = 0;
|
|
13
|
+
var handleNewEvent = false;
|
|
14
|
+
var isHandlingEvent;
|
|
15
|
+
var cdnBypass;
|
|
16
|
+
var backoff = new Backoff_1.Backoff(__handleSegmentUpdateCall, constants_1.FETCH_BACKOFF_BASE, constants_1.FETCH_BACKOFF_MAX_WAIT);
|
|
17
|
+
function __handleSegmentUpdateCall() {
|
|
18
|
+
isHandlingEvent = true;
|
|
19
|
+
if (maxChangeNumber > segmentsCache.getChangeNumber(segment)) {
|
|
20
|
+
handleNewEvent = false;
|
|
21
|
+
// fetch segments revalidating data if cached
|
|
22
|
+
segmentsSyncTask.execute(false, segment, true, cdnBypass ? maxChangeNumber : undefined).then(function () {
|
|
23
|
+
if (!isHandlingEvent)
|
|
24
|
+
return; // halt if `stop` has been called
|
|
25
|
+
if (handleNewEvent) {
|
|
26
|
+
__handleSegmentUpdateCall();
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
var attempts = backoff.attempts + 1;
|
|
30
|
+
if (maxChangeNumber <= segmentsCache.getChangeNumber(segment)) {
|
|
31
|
+
log.debug("Refresh completed" + (cdnBypass ? ' bypassing the CDN' : '') + " in " + attempts + " attempts.");
|
|
32
|
+
isHandlingEvent = false;
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
if (attempts < constants_1.FETCH_BACKOFF_MAX_RETRIES) {
|
|
36
|
+
backoff.scheduleCall();
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
if (cdnBypass) {
|
|
40
|
+
log.debug("No changes fetched after " + attempts + " attempts with CDN bypassed.");
|
|
41
|
+
isHandlingEvent = false;
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
backoff.reset();
|
|
45
|
+
cdnBypass = true;
|
|
46
|
+
__handleSegmentUpdateCall();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
isHandlingEvent = false;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
put: function (changeNumber) {
|
|
57
|
+
var currentChangeNumber = segmentsCache.getChangeNumber(segment);
|
|
58
|
+
if (changeNumber <= currentChangeNumber || changeNumber <= maxChangeNumber)
|
|
59
|
+
return;
|
|
60
|
+
maxChangeNumber = changeNumber;
|
|
61
|
+
handleNewEvent = true;
|
|
62
|
+
cdnBypass = false;
|
|
63
|
+
if (backoff.timeoutID || !isHandlingEvent)
|
|
64
|
+
__handleSegmentUpdateCall();
|
|
65
|
+
backoff.reset();
|
|
66
|
+
},
|
|
67
|
+
stop: function () {
|
|
68
|
+
isHandlingEvent = false;
|
|
69
|
+
backoff.reset();
|
|
70
|
+
}
|
|
71
|
+
};
|
|
21
72
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
segmentsToFetch.forEach(function (fetchedSegment, index) {
|
|
39
|
-
if (_this.maxChangeNumbers[fetchedSegment] === currentMaxChangeNumbers_1[index])
|
|
40
|
-
_this.maxChangeNumbers[fetchedSegment] = -1;
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
else {
|
|
44
|
-
// recursive invocation with backoff if there was some error
|
|
45
|
-
_this.backoff.scheduleCall();
|
|
46
|
-
}
|
|
47
|
-
// immediate recursive invocation if a new notification was queued during fetch
|
|
48
|
-
if (_this.handleNewEvent) {
|
|
49
|
-
_this.__handleSegmentUpdateCall();
|
|
50
|
-
}
|
|
51
|
-
});
|
|
73
|
+
var segments = {};
|
|
74
|
+
return {
|
|
75
|
+
/**
|
|
76
|
+
* Invoked by NotificationProcessor on SEGMENT_UPDATE event
|
|
77
|
+
*
|
|
78
|
+
* @param {number} changeNumber change number of the SEGMENT_UPDATE notification
|
|
79
|
+
* @param {string} segmentName segment name of the SEGMENT_UPDATE notification
|
|
80
|
+
*/
|
|
81
|
+
put: function (_a) {
|
|
82
|
+
var changeNumber = _a.changeNumber, segmentName = _a.segmentName;
|
|
83
|
+
if (!segments[segmentName])
|
|
84
|
+
segments[segmentName] = SegmentUpdateWorker(segmentName);
|
|
85
|
+
segments[segmentName].put(changeNumber);
|
|
86
|
+
},
|
|
87
|
+
stop: function () {
|
|
88
|
+
Object.keys(segments).forEach(function (segmentName) { return segments[segmentName].stop(); });
|
|
52
89
|
}
|
|
53
90
|
};
|
|
54
|
-
|
|
55
|
-
* Invoked by NotificationProcessor on SEGMENT_UPDATE event
|
|
56
|
-
*
|
|
57
|
-
* @param {number} changeNumber change number of the SEGMENT_UPDATE notification
|
|
58
|
-
* @param {string} segmentName segment name of the SEGMENT_UPDATE notification
|
|
59
|
-
*/
|
|
60
|
-
SegmentsUpdateWorker.prototype.put = function (_a) {
|
|
61
|
-
var changeNumber = _a.changeNumber, segmentName = _a.segmentName;
|
|
62
|
-
var currentChangeNumber = this.segmentsCache.getChangeNumber(segmentName);
|
|
63
|
-
if (changeNumber <= currentChangeNumber || changeNumber <= this.maxChangeNumbers[segmentName])
|
|
64
|
-
return;
|
|
65
|
-
this.maxChangeNumbers[segmentName] = changeNumber;
|
|
66
|
-
this.handleNewEvent = true;
|
|
67
|
-
this.backoff.reset();
|
|
68
|
-
if (this.segmentsSyncTask.isExecuting())
|
|
69
|
-
return;
|
|
70
|
-
this.__handleSegmentUpdateCall();
|
|
71
|
-
};
|
|
72
|
-
return SegmentsUpdateWorker;
|
|
73
|
-
}());
|
|
91
|
+
}
|
|
74
92
|
exports.SegmentsUpdateWorker = SegmentsUpdateWorker;
|