@splitsoftware/splitio-commons 1.16.0 → 1.16.1-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGES.txt +3 -0
- package/cjs/evaluator/matchers/index.js +3 -1
- package/cjs/evaluator/matchers/large_segment.js +16 -0
- package/cjs/evaluator/matchers/matcherTypes.js +1 -0
- package/cjs/evaluator/matchersTransform/index.js +1 -1
- package/cjs/logger/constants.js +4 -4
- package/cjs/logger/messages/info.js +0 -1
- package/cjs/readiness/readinessManager.js +11 -6
- package/cjs/readiness/sdkReadinessManager.js +5 -6
- package/cjs/sdkClient/sdkClientMethodCS.js +3 -4
- package/cjs/sdkClient/sdkClientMethodCSWithTT.js +4 -5
- package/cjs/sdkFactory/index.js +1 -1
- package/cjs/services/splitApi.js +4 -0
- package/cjs/storages/AbstractSplitsCacheAsync.js +2 -2
- package/cjs/storages/AbstractSplitsCacheSync.js +5 -5
- package/cjs/storages/KeyBuilder.js +3 -0
- package/cjs/storages/KeyBuilderCS.js +17 -5
- package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +16 -4
- package/cjs/storages/inLocalStorage/index.js +6 -2
- package/cjs/storages/inMemory/InMemoryStorageCS.js +5 -0
- package/cjs/storages/inMemory/SplitsCacheInMemory.js +20 -11
- package/cjs/storages/inMemory/TelemetryCacheInMemory.js +7 -10
- package/cjs/sync/polling/pollingManagerCS.js +54 -30
- package/cjs/sync/polling/syncTasks/mySegmentsSyncTask.js +2 -2
- package/cjs/sync/polling/updaters/mySegmentsUpdater.js +13 -8
- package/cjs/sync/polling/updaters/splitChangesUpdater.js +2 -1
- package/cjs/sync/streaming/SSEHandler/index.js +1 -0
- package/cjs/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +6 -5
- package/cjs/sync/streaming/constants.js +2 -1
- package/cjs/sync/streaming/pushManager.js +96 -64
- package/cjs/sync/submitters/telemetrySubmitter.js +2 -0
- package/cjs/sync/syncManagerOnline.js +24 -14
- package/cjs/utils/constants/index.js +5 -1
- package/cjs/utils/settingsValidation/index.js +9 -4
- package/esm/evaluator/matchers/index.js +3 -1
- package/esm/evaluator/matchers/large_segment.js +12 -0
- package/esm/evaluator/matchers/matcherTypes.js +1 -0
- package/esm/evaluator/matchersTransform/index.js +1 -1
- package/esm/logger/constants.js +1 -1
- package/esm/logger/messages/info.js +0 -1
- package/esm/readiness/readinessManager.js +11 -6
- package/esm/readiness/sdkReadinessManager.js +5 -6
- package/esm/sdkClient/sdkClientMethodCS.js +4 -5
- package/esm/sdkClient/sdkClientMethodCSWithTT.js +5 -6
- package/esm/sdkFactory/index.js +1 -1
- package/esm/services/splitApi.js +5 -1
- package/esm/storages/AbstractSplitsCacheAsync.js +2 -2
- package/esm/storages/AbstractSplitsCacheSync.js +3 -3
- package/esm/storages/KeyBuilder.js +3 -0
- package/esm/storages/KeyBuilderCS.js +15 -4
- package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +17 -5
- package/esm/storages/inLocalStorage/index.js +7 -3
- package/esm/storages/inMemory/InMemoryStorageCS.js +5 -0
- package/esm/storages/inMemory/SplitsCacheInMemory.js +21 -12
- package/esm/storages/inMemory/TelemetryCacheInMemory.js +7 -10
- package/esm/sync/polling/pollingManagerCS.js +55 -31
- package/esm/sync/polling/syncTasks/mySegmentsSyncTask.js +2 -2
- package/esm/sync/polling/updaters/mySegmentsUpdater.js +11 -6
- package/esm/sync/polling/updaters/splitChangesUpdater.js +2 -1
- package/esm/sync/streaming/SSEHandler/index.js +2 -1
- package/esm/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +6 -5
- package/esm/sync/streaming/constants.js +1 -0
- package/esm/sync/streaming/pushManager.js +96 -65
- package/esm/sync/submitters/telemetrySubmitter.js +2 -0
- package/esm/sync/syncManagerOnline.js +25 -15
- package/esm/utils/constants/index.js +4 -0
- package/esm/utils/settingsValidation/index.js +10 -5
- package/package.json +1 -1
- package/src/dtos/types.ts +7 -1
- package/src/evaluator/matchers/index.ts +2 -0
- package/src/evaluator/matchers/large_segment.ts +18 -0
- package/src/evaluator/matchers/matcherTypes.ts +1 -0
- package/src/evaluator/matchersTransform/index.ts +1 -1
- package/src/logger/constants.ts +1 -1
- package/src/logger/messages/info.ts +0 -1
- package/src/readiness/readinessManager.ts +11 -5
- package/src/readiness/sdkReadinessManager.ts +7 -7
- package/src/readiness/types.ts +3 -2
- package/src/sdkClient/sdkClientMethodCS.ts +4 -6
- package/src/sdkClient/sdkClientMethodCSWithTT.ts +5 -7
- package/src/sdkFactory/index.ts +1 -1
- package/src/services/splitApi.ts +6 -1
- package/src/services/types.ts +1 -0
- package/src/storages/AbstractSplitsCacheAsync.ts +2 -2
- package/src/storages/AbstractSplitsCacheSync.ts +4 -4
- package/src/storages/KeyBuilder.ts +3 -0
- package/src/storages/KeyBuilderCS.ts +25 -5
- package/src/storages/inLocalStorage/MySegmentsCacheInLocal.ts +3 -3
- package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +20 -5
- package/src/storages/inLocalStorage/index.ts +8 -4
- package/src/storages/inMemory/InMemoryStorageCS.ts +5 -0
- package/src/storages/inMemory/SplitsCacheInMemory.ts +15 -10
- package/src/storages/inMemory/TelemetryCacheInMemory.ts +7 -11
- package/src/storages/types.ts +6 -4
- package/src/sync/polling/pollingManagerCS.ts +62 -27
- package/src/sync/polling/syncTasks/mySegmentsSyncTask.ts +8 -9
- package/src/sync/polling/types.ts +4 -3
- package/src/sync/polling/updaters/mySegmentsUpdater.ts +13 -10
- package/src/sync/polling/updaters/splitChangesUpdater.ts +4 -3
- package/src/sync/streaming/SSEHandler/index.ts +2 -1
- package/src/sync/streaming/SSEHandler/types.ts +14 -2
- package/src/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.ts +7 -5
- package/src/sync/streaming/constants.ts +1 -0
- package/src/sync/streaming/pushManager.ts +101 -63
- package/src/sync/streaming/types.ts +5 -3
- package/src/sync/submitters/telemetrySubmitter.ts +2 -0
- package/src/sync/submitters/types.ts +10 -4
- package/src/sync/syncManagerOnline.ts +19 -11
- package/src/types.ts +26 -1
- package/src/utils/constants/index.ts +5 -0
- package/src/utils/settingsValidation/index.ts +11 -6
- package/src/utils/settingsValidation/types.ts +1 -1
- package/types/dtos/types.d.ts +5 -1
- package/types/evaluator/matchers/large_segment.d.ts +5 -0
- package/types/logger/constants.d.ts +1 -1
- package/types/readiness/readinessManager.d.ts +2 -2
- package/types/readiness/sdkReadinessManager.d.ts +2 -3
- package/types/readiness/types.d.ts +3 -2
- package/types/services/types.d.ts +1 -0
- package/types/storages/AbstractSplitsCacheAsync.d.ts +1 -1
- package/types/storages/AbstractSplitsCacheSync.d.ts +3 -3
- package/types/storages/KeyBuilder.d.ts +1 -0
- package/types/storages/KeyBuilderCS.d.ts +7 -2
- package/types/storages/inLocalStorage/MySegmentsCacheInLocal.d.ts +2 -2
- package/types/storages/inLocalStorage/SplitsCacheInLocal.d.ts +1 -1
- package/types/storages/inMemory/SplitsCacheInMemory.d.ts +3 -2
- package/types/storages/inMemory/TelemetryCacheInMemory.d.ts +4 -6
- package/types/storages/types.d.ts +4 -3
- package/types/sync/polling/syncTasks/mySegmentsSyncTask.d.ts +2 -3
- package/types/sync/polling/types.d.ts +10 -3
- package/types/sync/polling/updaters/mySegmentsUpdater.d.ts +4 -4
- package/types/sync/streaming/SSEHandler/types.d.ts +13 -2
- package/types/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.d.ts +2 -1
- package/types/sync/streaming/constants.d.ts +1 -0
- package/types/sync/streaming/pushManager.d.ts +2 -0
- package/types/sync/streaming/types.d.ts +5 -4
- package/types/sync/submitters/types.d.ts +9 -3
- package/types/types.d.ts +25 -0
- package/types/utils/constants/index.d.ts +3 -0
- package/types/utils/settingsValidation/index.d.ts +2 -0
- package/types/utils/settingsValidation/types.d.ts +1 -1
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { __extends } from "tslib";
|
|
2
|
-
import { AbstractSplitsCacheSync,
|
|
2
|
+
import { AbstractSplitsCacheSync, usesMatcher } from '../AbstractSplitsCacheSync';
|
|
3
3
|
import { isFiniteNumber } from '../../utils/lang';
|
|
4
4
|
import { _Set } from '../../utils/lang/sets';
|
|
5
|
+
import { IN_LARGE_SEGMENT, IN_SEGMENT } from '../../utils/constants';
|
|
5
6
|
/**
|
|
6
7
|
* Default ISplitsCacheSync implementation that stores split definitions in memory.
|
|
7
8
|
* Supported by all JS runtimes.
|
|
@@ -13,7 +14,8 @@ var SplitsCacheInMemory = /** @class */ (function (_super) {
|
|
|
13
14
|
_this.splitsCache = {};
|
|
14
15
|
_this.ttCache = {};
|
|
15
16
|
_this.changeNumber = -1;
|
|
16
|
-
_this.
|
|
17
|
+
_this.segmentsCount = 0;
|
|
18
|
+
_this.largeSegmentsCount = 0;
|
|
17
19
|
_this.flagSetsCache = {};
|
|
18
20
|
_this.flagSetsFilter = splitFiltersValidation ? splitFiltersValidation.groupedFilters.bySet : [];
|
|
19
21
|
return _this;
|
|
@@ -22,7 +24,8 @@ var SplitsCacheInMemory = /** @class */ (function (_super) {
|
|
|
22
24
|
this.splitsCache = {};
|
|
23
25
|
this.ttCache = {};
|
|
24
26
|
this.changeNumber = -1;
|
|
25
|
-
this.
|
|
27
|
+
this.segmentsCount = 0;
|
|
28
|
+
this.largeSegmentsCount = 0;
|
|
26
29
|
};
|
|
27
30
|
SplitsCacheInMemory.prototype.addSplit = function (name, split) {
|
|
28
31
|
var previousSplit = this.getSplit(name);
|
|
@@ -32,9 +35,11 @@ var SplitsCacheInMemory = /** @class */ (function (_super) {
|
|
|
32
35
|
if (!this.ttCache[previousTtName])
|
|
33
36
|
delete this.ttCache[previousTtName];
|
|
34
37
|
this.removeFromFlagSets(previousSplit.name, previousSplit.sets);
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
+
// Substract from segments count for the previous version of this Split.
|
|
39
|
+
if (usesMatcher(previousSplit, IN_SEGMENT))
|
|
40
|
+
this.segmentsCount--;
|
|
41
|
+
if (usesMatcher(previousSplit, IN_LARGE_SEGMENT))
|
|
42
|
+
this.largeSegmentsCount--;
|
|
38
43
|
}
|
|
39
44
|
if (split) {
|
|
40
45
|
// Store the Split.
|
|
@@ -44,8 +49,10 @@ var SplitsCacheInMemory = /** @class */ (function (_super) {
|
|
|
44
49
|
this.ttCache[ttName] = (this.ttCache[ttName] || 0) + 1;
|
|
45
50
|
this.addToFlagSets(split);
|
|
46
51
|
// Add to segments count for the new version of the Split
|
|
47
|
-
if (
|
|
48
|
-
this.
|
|
52
|
+
if (usesMatcher(split, IN_SEGMENT))
|
|
53
|
+
this.segmentsCount++;
|
|
54
|
+
if (usesMatcher(split, IN_LARGE_SEGMENT))
|
|
55
|
+
this.largeSegmentsCount++;
|
|
49
56
|
return true;
|
|
50
57
|
}
|
|
51
58
|
else {
|
|
@@ -63,8 +70,10 @@ var SplitsCacheInMemory = /** @class */ (function (_super) {
|
|
|
63
70
|
delete this.ttCache[ttName];
|
|
64
71
|
this.removeFromFlagSets(split.name, split.sets);
|
|
65
72
|
// Update the segments count.
|
|
66
|
-
if (
|
|
67
|
-
this.
|
|
73
|
+
if (usesMatcher(split, IN_SEGMENT))
|
|
74
|
+
this.segmentsCount--;
|
|
75
|
+
if (usesMatcher(split, IN_LARGE_SEGMENT))
|
|
76
|
+
this.largeSegmentsCount--;
|
|
68
77
|
return true;
|
|
69
78
|
}
|
|
70
79
|
else {
|
|
@@ -87,8 +96,8 @@ var SplitsCacheInMemory = /** @class */ (function (_super) {
|
|
|
87
96
|
SplitsCacheInMemory.prototype.trafficTypeExists = function (trafficType) {
|
|
88
97
|
return isFiniteNumber(this.ttCache[trafficType]) && this.ttCache[trafficType] > 0;
|
|
89
98
|
};
|
|
90
|
-
SplitsCacheInMemory.prototype.
|
|
91
|
-
return this.getChangeNumber() === -1 || this.
|
|
99
|
+
SplitsCacheInMemory.prototype.usesMatcher = function (matcherType) {
|
|
100
|
+
return this.getChangeNumber() === -1 || (matcherType === IN_SEGMENT ? this.segmentsCount > 0 : this.largeSegmentsCount > 0);
|
|
92
101
|
};
|
|
93
102
|
SplitsCacheInMemory.prototype.getNamesByFlagSets = function (flagSets) {
|
|
94
103
|
var _this = this;
|
|
@@ -18,9 +18,10 @@ export function shouldRecordTelemetry(_a) {
|
|
|
18
18
|
return settings.mode !== LOCALHOST_MODE && (settings.core.key === undefined || Math.random() <= ACCEPTANCE_RANGE);
|
|
19
19
|
}
|
|
20
20
|
var TelemetryCacheInMemory = /** @class */ (function () {
|
|
21
|
-
function TelemetryCacheInMemory(splits, segments) {
|
|
21
|
+
function TelemetryCacheInMemory(splits, segments, largeSegments) {
|
|
22
22
|
this.splits = splits;
|
|
23
23
|
this.segments = segments;
|
|
24
|
+
this.largeSegments = largeSegments;
|
|
24
25
|
// isEmpty flag
|
|
25
26
|
this.e = true;
|
|
26
27
|
this.notReadyUsage = 0;
|
|
@@ -36,10 +37,7 @@ var TelemetryCacheInMemory = /** @class */ (function () {
|
|
|
36
37
|
this.tags = [];
|
|
37
38
|
this.exceptions = {};
|
|
38
39
|
this.latencies = {};
|
|
39
|
-
this.updatesFromSSE = {
|
|
40
|
-
sp: 0,
|
|
41
|
-
ms: 0
|
|
42
|
-
};
|
|
40
|
+
this.updatesFromSSE = {};
|
|
43
41
|
}
|
|
44
42
|
TelemetryCacheInMemory.prototype.isEmpty = function () { return this.e; };
|
|
45
43
|
TelemetryCacheInMemory.prototype.clear = function () { };
|
|
@@ -59,6 +57,8 @@ var TelemetryCacheInMemory = /** @class */ (function () {
|
|
|
59
57
|
spC: this.splits && this.splits.getSplitNames().length,
|
|
60
58
|
seC: this.segments && this.segments.getRegisteredSegments().length,
|
|
61
59
|
skC: this.segments && this.segments.getKeysCount(),
|
|
60
|
+
lseC: this.largeSegments && this.largeSegments.getRegisteredSegments().length,
|
|
61
|
+
lskC: this.largeSegments && this.largeSegments.getKeysCount(),
|
|
62
62
|
sL: this.getSessionLength(),
|
|
63
63
|
eQ: this.getEventStats(QUEUED),
|
|
64
64
|
eD: this.getEventStats(DROPPED),
|
|
@@ -190,14 +190,11 @@ var TelemetryCacheInMemory = /** @class */ (function () {
|
|
|
190
190
|
};
|
|
191
191
|
TelemetryCacheInMemory.prototype.popUpdatesFromSSE = function () {
|
|
192
192
|
var result = this.updatesFromSSE;
|
|
193
|
-
this.updatesFromSSE = {
|
|
194
|
-
sp: 0,
|
|
195
|
-
ms: 0,
|
|
196
|
-
};
|
|
193
|
+
this.updatesFromSSE = {};
|
|
197
194
|
return result;
|
|
198
195
|
};
|
|
199
196
|
TelemetryCacheInMemory.prototype.recordUpdatesFromSSE = function (type) {
|
|
200
|
-
this.updatesFromSSE[type]
|
|
197
|
+
this.updatesFromSSE[type] = (this.updatesFromSSE[type] || 0) + 1;
|
|
201
198
|
this.e = false;
|
|
202
199
|
};
|
|
203
200
|
return TelemetryCacheInMemory;
|
|
@@ -3,7 +3,8 @@ import { mySegmentsSyncTaskFactory } from './syncTasks/mySegmentsSyncTask';
|
|
|
3
3
|
import { splitsSyncTaskFactory } from './syncTasks/splitsSyncTask';
|
|
4
4
|
import { getMatching } from '../../utils/key';
|
|
5
5
|
import { SDK_SPLITS_ARRIVED, SDK_SEGMENTS_ARRIVED } from '../../readiness/constants';
|
|
6
|
-
import {
|
|
6
|
+
import { POLLING_START, POLLING_STOP } from '../../logger/constants';
|
|
7
|
+
import { IN_LARGE_SEGMENT, IN_SEGMENT } from '../../utils/constants';
|
|
7
8
|
/**
|
|
8
9
|
* Expose start / stop mechanism for polling data from services.
|
|
9
10
|
* For client-side API with multiple clients.
|
|
@@ -12,59 +13,80 @@ export function pollingManagerCSFactory(params) {
|
|
|
12
13
|
var splitApi = params.splitApi, storage = params.storage, readiness = params.readiness, settings = params.settings;
|
|
13
14
|
var log = settings.log;
|
|
14
15
|
var splitsSyncTask = splitsSyncTaskFactory(splitApi.fetchSplitChanges, storage, readiness, settings, true);
|
|
15
|
-
// Map of matching keys to their corresponding MySegmentsSyncTask.
|
|
16
|
+
// Map of matching keys to their corresponding MySegmentsSyncTask for segments and large segments.
|
|
16
17
|
var mySegmentsSyncTasks = {};
|
|
17
18
|
var matchingKey = getMatching(settings.core.key);
|
|
18
|
-
var
|
|
19
|
+
var _a = add(matchingKey, readiness, storage), msSyncTask = _a.msSyncTask, mlsSyncTask = _a.mlsSyncTask;
|
|
19
20
|
function startMySegmentsSyncTasks() {
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
var splitsHaveSegments = storage.splits.usesMatcher(IN_SEGMENT);
|
|
22
|
+
var splitsHaveLargeSegments = storage.splits.usesMatcher(IN_LARGE_SEGMENT);
|
|
23
|
+
forOwn(mySegmentsSyncTasks, function (_a) {
|
|
24
|
+
var msSyncTask = _a.msSyncTask, mlsSyncTask = _a.mlsSyncTask;
|
|
25
|
+
if (splitsHaveSegments)
|
|
26
|
+
msSyncTask.start();
|
|
27
|
+
else
|
|
28
|
+
msSyncTask.stop();
|
|
29
|
+
if (mlsSyncTask) {
|
|
30
|
+
if (splitsHaveLargeSegments)
|
|
31
|
+
mlsSyncTask.start();
|
|
32
|
+
else
|
|
33
|
+
mlsSyncTask.stop();
|
|
34
|
+
}
|
|
22
35
|
});
|
|
23
36
|
}
|
|
24
37
|
function stopMySegmentsSyncTasks() {
|
|
25
|
-
forOwn(mySegmentsSyncTasks, function (
|
|
26
|
-
|
|
27
|
-
|
|
38
|
+
forOwn(mySegmentsSyncTasks, function (_a) {
|
|
39
|
+
var msSyncTask = _a.msSyncTask, mlsSyncTask = _a.mlsSyncTask;
|
|
40
|
+
msSyncTask.stop();
|
|
41
|
+
mlsSyncTask && mlsSyncTask.stop();
|
|
28
42
|
});
|
|
29
43
|
}
|
|
30
44
|
// smart pausing
|
|
31
45
|
readiness.splits.on(SDK_SPLITS_ARRIVED, function () {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
if (splitsHaveSegments !== mySegmentsSyncTask.isRunning()) {
|
|
36
|
-
log.info(POLLING_SMART_PAUSING, [splitsHaveSegments ? 'ON' : 'OFF']);
|
|
37
|
-
if (splitsHaveSegments) {
|
|
38
|
-
startMySegmentsSyncTasks();
|
|
39
|
-
}
|
|
40
|
-
else {
|
|
41
|
-
stopMySegmentsSyncTasks();
|
|
42
|
-
}
|
|
43
|
-
}
|
|
46
|
+
// smart pausing of mySegments polling
|
|
47
|
+
if (splitsSyncTask.isRunning())
|
|
48
|
+
startMySegmentsSyncTasks();
|
|
44
49
|
});
|
|
45
50
|
function add(matchingKey, readiness, storage) {
|
|
46
|
-
var
|
|
51
|
+
var msSyncTask = mySegmentsSyncTaskFactory(splitApi.fetchMySegments, storage.segments, function () {
|
|
52
|
+
if (storage.splits.usesMatcher(IN_SEGMENT))
|
|
53
|
+
readiness.segments.emit(SDK_SEGMENTS_ARRIVED);
|
|
54
|
+
}, settings, matchingKey, settings.scheduler.segmentsRefreshRate);
|
|
55
|
+
var mlsSyncTask;
|
|
56
|
+
if (settings.sync.largeSegmentsEnabled) {
|
|
57
|
+
mlsSyncTask = mySegmentsSyncTaskFactory(splitApi.fetchMyLargeSegments, storage.largeSegments, function () {
|
|
58
|
+
if (readiness.largeSegments && storage.splits.usesMatcher(IN_LARGE_SEGMENT))
|
|
59
|
+
readiness.largeSegments.emit(SDK_SEGMENTS_ARRIVED);
|
|
60
|
+
}, settings, matchingKey, settings.scheduler.largeSegmentsRefreshRate);
|
|
61
|
+
}
|
|
47
62
|
// smart ready
|
|
48
63
|
function smartReady() {
|
|
49
|
-
if (!readiness.isReady()
|
|
50
|
-
|
|
64
|
+
if (!readiness.isReady()) {
|
|
65
|
+
if (!storage.splits.usesMatcher(IN_SEGMENT))
|
|
66
|
+
readiness.segments.emit(SDK_SEGMENTS_ARRIVED);
|
|
67
|
+
if (readiness.largeSegments && !storage.splits.usesMatcher(IN_LARGE_SEGMENT))
|
|
68
|
+
readiness.largeSegments.emit(SDK_SEGMENTS_ARRIVED);
|
|
69
|
+
}
|
|
51
70
|
}
|
|
52
|
-
if (!storage.splits.
|
|
71
|
+
if (!storage.splits.usesMatcher(IN_SEGMENT) && !storage.splits.usesMatcher(IN_LARGE_SEGMENT))
|
|
53
72
|
setTimeout(smartReady, 0);
|
|
54
73
|
else
|
|
55
74
|
readiness.splits.once(SDK_SPLITS_ARRIVED, smartReady);
|
|
56
|
-
mySegmentsSyncTasks[matchingKey] =
|
|
57
|
-
return
|
|
75
|
+
mySegmentsSyncTasks[matchingKey] = { msSyncTask: msSyncTask, mlsSyncTask: mlsSyncTask };
|
|
76
|
+
return {
|
|
77
|
+
msSyncTask: msSyncTask,
|
|
78
|
+
mlsSyncTask: mlsSyncTask
|
|
79
|
+
};
|
|
58
80
|
}
|
|
59
81
|
return {
|
|
60
82
|
splitsSyncTask: splitsSyncTask,
|
|
61
|
-
segmentsSyncTask:
|
|
83
|
+
segmentsSyncTask: msSyncTask,
|
|
84
|
+
largeSegmentsSyncTask: mlsSyncTask,
|
|
62
85
|
// Start periodic fetching (polling)
|
|
63
86
|
start: function () {
|
|
64
87
|
log.info(POLLING_START);
|
|
65
88
|
splitsSyncTask.start();
|
|
66
|
-
|
|
67
|
-
startMySegmentsSyncTasks();
|
|
89
|
+
startMySegmentsSyncTasks();
|
|
68
90
|
},
|
|
69
91
|
// Stop periodic fetching (polling)
|
|
70
92
|
stop: function () {
|
|
@@ -78,8 +100,10 @@ export function pollingManagerCSFactory(params) {
|
|
|
78
100
|
// fetch splits and segments
|
|
79
101
|
syncAll: function () {
|
|
80
102
|
var promises = [splitsSyncTask.execute()];
|
|
81
|
-
forOwn(mySegmentsSyncTasks, function (
|
|
82
|
-
|
|
103
|
+
forOwn(mySegmentsSyncTasks, function (_a) {
|
|
104
|
+
var msSyncTask = _a.msSyncTask, mlsSyncTask = _a.mlsSyncTask;
|
|
105
|
+
promises.push(msSyncTask.execute());
|
|
106
|
+
mlsSyncTask && promises.push(mlsSyncTask.execute());
|
|
83
107
|
});
|
|
84
108
|
return Promise.all(promises);
|
|
85
109
|
},
|
|
@@ -4,6 +4,6 @@ import { mySegmentsUpdaterFactory } from '../updaters/mySegmentsUpdater';
|
|
|
4
4
|
/**
|
|
5
5
|
* Creates a sync task that periodically executes a `mySegmentsUpdater` task
|
|
6
6
|
*/
|
|
7
|
-
export function mySegmentsSyncTaskFactory(fetchMySegments,
|
|
8
|
-
return syncTaskFactory(settings.log, mySegmentsUpdaterFactory(settings.log, mySegmentsFetcherFactory(fetchMySegments),
|
|
7
|
+
export function mySegmentsSyncTaskFactory(fetchMySegments, mySegmentsCache, notifyUpdate, settings, matchingKey, segmentsRefreshRate) {
|
|
8
|
+
return syncTaskFactory(settings.log, mySegmentsUpdaterFactory(settings.log, mySegmentsFetcherFactory(fetchMySegments), mySegmentsCache, notifyUpdate, settings.startup.requestTimeoutBeforeReady, settings.startup.retriesOnFailureBeforeReady, matchingKey), segmentsRefreshRate, 'mySegmentsUpdater');
|
|
9
9
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { timeout } from '../../../utils/promise/timeout';
|
|
2
|
-
import { SDK_SEGMENTS_ARRIVED } from '../../../readiness/constants';
|
|
3
2
|
import { SYNC_MYSEGMENTS_FETCH_RETRY } from '../../../logger/constants';
|
|
4
3
|
/**
|
|
5
4
|
* factory of MySegments updater, a task that:
|
|
@@ -7,7 +6,7 @@ import { SYNC_MYSEGMENTS_FETCH_RETRY } from '../../../logger/constants';
|
|
|
7
6
|
* - updates `mySegmentsCache`
|
|
8
7
|
* - uses `segmentsEventEmitter` to emit events related to segments data updates
|
|
9
8
|
*/
|
|
10
|
-
export function mySegmentsUpdaterFactory(log, mySegmentsFetcher,
|
|
9
|
+
export function mySegmentsUpdaterFactory(log, mySegmentsFetcher, mySegmentsCache, notifyUpdate, requestTimeoutBeforeReady, retriesOnFailureBeforeReady, matchingKey) {
|
|
11
10
|
var readyOnAlreadyExistentState = true;
|
|
12
11
|
var startingUp = true;
|
|
13
12
|
/** timeout and telemetry decorator for `splitChangesFetcher` promise */
|
|
@@ -38,9 +37,9 @@ export function mySegmentsUpdaterFactory(log, mySegmentsFetcher, splitsCache, my
|
|
|
38
37
|
}
|
|
39
38
|
}
|
|
40
39
|
// Notify update if required
|
|
41
|
-
if (
|
|
40
|
+
if (shouldNotifyUpdate || readyOnAlreadyExistentState) {
|
|
42
41
|
readyOnAlreadyExistentState = false;
|
|
43
|
-
|
|
42
|
+
notifyUpdate();
|
|
44
43
|
}
|
|
45
44
|
}
|
|
46
45
|
function _mySegmentsUpdater(retry, segmentsData, noCache) {
|
|
@@ -76,7 +75,13 @@ export function mySegmentsUpdaterFactory(log, mySegmentsFetcher, splitsCache, my
|
|
|
76
75
|
* (3) or `undefined`, for which the updater will fetch mySegments in order to sync the storage.
|
|
77
76
|
* @param {boolean | undefined} noCache true to revalidate data to fetch
|
|
78
77
|
*/
|
|
79
|
-
return function mySegmentsUpdater(segmentsData, noCache) {
|
|
80
|
-
return
|
|
78
|
+
return function mySegmentsUpdater(segmentsData, noCache, delay) {
|
|
79
|
+
return delay ?
|
|
80
|
+
new Promise(function (res) {
|
|
81
|
+
setTimeout(function () {
|
|
82
|
+
_mySegmentsUpdater(0, segmentsData, noCache).then(res);
|
|
83
|
+
}, delay);
|
|
84
|
+
}) :
|
|
85
|
+
_mySegmentsUpdater(0, segmentsData, noCache);
|
|
81
86
|
};
|
|
82
87
|
}
|
|
@@ -3,6 +3,7 @@ import { timeout } from '../../../utils/promise/timeout';
|
|
|
3
3
|
import { SDK_SPLITS_ARRIVED, SDK_SPLITS_CACHE_LOADED } from '../../../readiness/constants';
|
|
4
4
|
import { SYNC_SPLITS_FETCH, SYNC_SPLITS_NEW, SYNC_SPLITS_REMOVED, SYNC_SPLITS_SEGMENTS, SYNC_SPLITS_FETCH_FAILS, SYNC_SPLITS_FETCH_RETRY } from '../../../logger/constants';
|
|
5
5
|
import { startsWith } from '../../../utils/lang';
|
|
6
|
+
import { IN_SEGMENT } from '../../../utils/constants';
|
|
6
7
|
// Checks that all registered segments have been fetched (changeNumber !== -1 for every segment).
|
|
7
8
|
// Returns a promise that could be rejected.
|
|
8
9
|
// @TODO review together with Segments and MySegments storage APIs
|
|
@@ -23,7 +24,7 @@ export function parseSegments(_a) {
|
|
|
23
24
|
for (var i = 0; i < conditions.length; i++) {
|
|
24
25
|
var matchers = conditions[i].matcherGroup.matchers;
|
|
25
26
|
matchers.forEach(function (matcher) {
|
|
26
|
-
if (matcher.matcherType ===
|
|
27
|
+
if (matcher.matcherType === IN_SEGMENT)
|
|
27
28
|
segments.add(matcher.userDefinedSegmentMatcherData.segmentName);
|
|
28
29
|
});
|
|
29
30
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { errorParser, messageParser } from './NotificationParser';
|
|
2
2
|
import { notificationKeeperFactory } from './NotificationKeeper';
|
|
3
|
-
import { PUSH_RETRYABLE_ERROR, PUSH_NONRETRYABLE_ERROR, OCCUPANCY, CONTROL, MY_SEGMENTS_UPDATE, MY_SEGMENTS_UPDATE_V2, SEGMENT_UPDATE, SPLIT_KILL, SPLIT_UPDATE } from '../constants';
|
|
3
|
+
import { PUSH_RETRYABLE_ERROR, PUSH_NONRETRYABLE_ERROR, OCCUPANCY, CONTROL, MY_SEGMENTS_UPDATE, MY_SEGMENTS_UPDATE_V2, SEGMENT_UPDATE, SPLIT_KILL, SPLIT_UPDATE, MY_LARGE_SEGMENTS_UPDATE } from '../constants';
|
|
4
4
|
import { STREAMING_PARSING_ERROR_FAILS, ERROR_STREAMING_SSE, STREAMING_PARSING_MESSAGE_FAILS, STREAMING_NEW_MESSAGE } from '../../../logger/constants';
|
|
5
5
|
import { ABLY_ERROR, NON_REQUESTED, SSE_CONNECTION_ERROR } from '../../../utils/constants';
|
|
6
6
|
/**
|
|
@@ -73,6 +73,7 @@ export function SSEHandlerFactory(log, pushEmitter, telemetryTracker) {
|
|
|
73
73
|
case SPLIT_UPDATE:
|
|
74
74
|
case SEGMENT_UPDATE:
|
|
75
75
|
case MY_SEGMENTS_UPDATE_V2:
|
|
76
|
+
case MY_LARGE_SEGMENTS_UPDATE:
|
|
76
77
|
case SPLIT_KILL:
|
|
77
78
|
pushEmitter.emit(parsedData.type, parsedData);
|
|
78
79
|
break;
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { Backoff } from '../../../utils/Backoff';
|
|
2
|
-
import { MY_SEGMENT } from '../../../utils/constants';
|
|
3
2
|
/**
|
|
4
3
|
* MySegmentsUpdateWorker factory
|
|
5
4
|
*/
|
|
6
|
-
export function MySegmentsUpdateWorker(mySegmentsSyncTask, telemetryTracker) {
|
|
5
|
+
export function MySegmentsUpdateWorker(mySegmentsSyncTask, telemetryTracker, updateType) {
|
|
7
6
|
var maxChangeNumber = 0; // keeps the maximum changeNumber among queued events
|
|
8
7
|
var currentChangeNumber = -1;
|
|
9
8
|
var handleNewEvent = false;
|
|
10
9
|
var isHandlingEvent;
|
|
11
10
|
var _segmentsData; // keeps the segmentsData (if included in notification payload) from the queued event with maximum changeNumber
|
|
11
|
+
var _delay;
|
|
12
12
|
var backoff = new Backoff(__handleMySegmentsUpdateCall);
|
|
13
13
|
function __handleMySegmentsUpdateCall() {
|
|
14
14
|
isHandlingEvent = true;
|
|
@@ -16,12 +16,12 @@ export function MySegmentsUpdateWorker(mySegmentsSyncTask, telemetryTracker) {
|
|
|
16
16
|
handleNewEvent = false;
|
|
17
17
|
var currentMaxChangeNumber_1 = maxChangeNumber;
|
|
18
18
|
// fetch mySegments revalidating data if cached
|
|
19
|
-
mySegmentsSyncTask.execute(_segmentsData, true).then(function (result) {
|
|
19
|
+
mySegmentsSyncTask.execute(_segmentsData, true, _delay).then(function (result) {
|
|
20
20
|
if (!isHandlingEvent)
|
|
21
21
|
return; // halt if `stop` has been called
|
|
22
22
|
if (result !== false) { // Unlike `Splits|SegmentsUpdateWorker`, we cannot use `mySegmentsCache.getChangeNumber` since `/mySegments` endpoint doesn't provide this value.
|
|
23
23
|
if (_segmentsData)
|
|
24
|
-
telemetryTracker.trackUpdatesFromSSE(
|
|
24
|
+
telemetryTracker.trackUpdatesFromSSE(updateType);
|
|
25
25
|
currentChangeNumber = Math.max(currentChangeNumber, currentMaxChangeNumber_1); // use `currentMaxChangeNumber`, in case that `maxChangeNumber` was updated during fetch.
|
|
26
26
|
}
|
|
27
27
|
if (handleNewEvent) {
|
|
@@ -43,12 +43,13 @@ export function MySegmentsUpdateWorker(mySegmentsSyncTask, telemetryTracker) {
|
|
|
43
43
|
* @param {number} changeNumber change number of the MY_SEGMENTS_UPDATE notification
|
|
44
44
|
* @param {SegmentsData | undefined} segmentsData might be undefined
|
|
45
45
|
*/
|
|
46
|
-
put: function (changeNumber, segmentsData) {
|
|
46
|
+
put: function (changeNumber, segmentsData, delay) {
|
|
47
47
|
if (changeNumber <= currentChangeNumber || changeNumber <= maxChangeNumber)
|
|
48
48
|
return;
|
|
49
49
|
maxChangeNumber = changeNumber;
|
|
50
50
|
handleNewEvent = true;
|
|
51
51
|
_segmentsData = segmentsData;
|
|
52
|
+
_delay = delay;
|
|
52
53
|
if (backoff.timeoutID || !isHandlingEvent)
|
|
53
54
|
__handleMySegmentsUpdateCall();
|
|
54
55
|
backoff.reset();
|
|
@@ -27,6 +27,7 @@ export var MY_SEGMENTS_UPDATE_V2 = 'MY_SEGMENTS_UPDATE_V2';
|
|
|
27
27
|
export var SEGMENT_UPDATE = 'SEGMENT_UPDATE';
|
|
28
28
|
export var SPLIT_KILL = 'SPLIT_KILL';
|
|
29
29
|
export var SPLIT_UPDATE = 'SPLIT_UPDATE';
|
|
30
|
+
export var MY_LARGE_SEGMENTS_UPDATE = 'MY_LARGE_SEGMENTS_UPDATE';
|
|
30
31
|
// Control-type push notifications, handled by NotificationKeeper
|
|
31
32
|
export var CONTROL = 'CONTROL';
|
|
32
33
|
export var OCCUPANCY = 'OCCUPANCY';
|
|
@@ -8,13 +8,20 @@ import { authenticateFactory, hashUserKey } from './AuthClient';
|
|
|
8
8
|
import { forOwn } from '../../utils/lang';
|
|
9
9
|
import { SSEClient } from './SSEClient';
|
|
10
10
|
import { getMatching } from '../../utils/key';
|
|
11
|
-
import { MY_SEGMENTS_UPDATE, MY_SEGMENTS_UPDATE_V2, PUSH_NONRETRYABLE_ERROR, PUSH_SUBSYSTEM_DOWN, SECONDS_BEFORE_EXPIRATION, SEGMENT_UPDATE, SPLIT_KILL, SPLIT_UPDATE, PUSH_RETRYABLE_ERROR, PUSH_SUBSYSTEM_UP, ControlType } from './constants';
|
|
11
|
+
import { MY_SEGMENTS_UPDATE, MY_SEGMENTS_UPDATE_V2, PUSH_NONRETRYABLE_ERROR, PUSH_SUBSYSTEM_DOWN, SECONDS_BEFORE_EXPIRATION, SEGMENT_UPDATE, SPLIT_KILL, SPLIT_UPDATE, PUSH_RETRYABLE_ERROR, PUSH_SUBSYSTEM_UP, ControlType, MY_LARGE_SEGMENTS_UPDATE } from './constants';
|
|
12
12
|
import { STREAMING_FALLBACK, STREAMING_REFRESH_TOKEN, STREAMING_CONNECTING, STREAMING_DISABLED, ERROR_STREAMING_AUTH, STREAMING_DISCONNECTING, STREAMING_RECONNECT, STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2, STREAMING_PARSING_SPLIT_UPDATE } from '../../logger/constants';
|
|
13
13
|
import { UpdateStrategy } from './SSEHandler/types';
|
|
14
14
|
import { isInBitmap, parseBitmap, parseFFUpdatePayload, parseKeyList } from './parseUtils';
|
|
15
15
|
import { _Set } from '../../utils/lang/sets';
|
|
16
|
+
import { hash } from '../../utils/murmur3/murmur3';
|
|
16
17
|
import { hash64 } from '../../utils/murmur3/murmur3_64';
|
|
17
|
-
import { TOKEN_REFRESH, AUTH_REJECTION } from '../../utils/constants';
|
|
18
|
+
import { TOKEN_REFRESH, AUTH_REJECTION, MY_LARGE_SEGMENT, MY_SEGMENT } from '../../utils/constants';
|
|
19
|
+
export function getDelay(parsedData, matchingKey) {
|
|
20
|
+
var interval = parsedData.i || 60000;
|
|
21
|
+
// const hashType = parsedData.h || 0;
|
|
22
|
+
var seed = parsedData.s || 0;
|
|
23
|
+
return hash(matchingKey, seed) % interval;
|
|
24
|
+
}
|
|
18
25
|
/**
|
|
19
26
|
* PushManager factory:
|
|
20
27
|
* - for server-side if key is not provided in settings.
|
|
@@ -140,8 +147,9 @@ export function pushManagerFactory(params, pollingManager) {
|
|
|
140
147
|
splitsUpdateWorker.stop();
|
|
141
148
|
if (userKey)
|
|
142
149
|
forOwn(clients, function (_a) {
|
|
143
|
-
var worker = _a.worker;
|
|
144
|
-
|
|
150
|
+
var worker = _a.worker, workerLarge = _a.workerLarge;
|
|
151
|
+
worker.stop();
|
|
152
|
+
workerLarge && workerLarge.stop();
|
|
145
153
|
});
|
|
146
154
|
else
|
|
147
155
|
segmentsUpdateWorker.stop();
|
|
@@ -195,77 +203,96 @@ export function pushManagerFactory(params, pollingManager) {
|
|
|
195
203
|
}
|
|
196
204
|
splitsUpdateWorker.put(parsedData);
|
|
197
205
|
});
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
});
|
|
206
|
-
pushEmitter.on(MY_SEGMENTS_UPDATE_V2, function handleMySegmentsUpdate(parsedData) {
|
|
207
|
-
switch (parsedData.u) {
|
|
208
|
-
case UpdateStrategy.BoundedFetchRequest: {
|
|
209
|
-
var bitmap_1;
|
|
210
|
-
try {
|
|
211
|
-
bitmap_1 = parseBitmap(parsedData.d, parsedData.c);
|
|
212
|
-
}
|
|
213
|
-
catch (e) {
|
|
214
|
-
log.warn(STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2, ['BoundedFetchRequest', e]);
|
|
215
|
-
break;
|
|
216
|
-
}
|
|
217
|
-
forOwn(clients, function (_a) {
|
|
218
|
-
var hash64 = _a.hash64, worker = _a.worker;
|
|
219
|
-
if (isInBitmap(bitmap_1, hash64.hex)) {
|
|
220
|
-
worker.put(parsedData.changeNumber); // fetch mySegments
|
|
221
|
-
}
|
|
222
|
-
});
|
|
223
|
-
return;
|
|
206
|
+
function handleMySegmentsUpdate(parsedData) {
|
|
207
|
+
var isLS = parsedData.type === MY_LARGE_SEGMENTS_UPDATE;
|
|
208
|
+
switch (parsedData.u) {
|
|
209
|
+
case UpdateStrategy.BoundedFetchRequest: {
|
|
210
|
+
var bitmap_1;
|
|
211
|
+
try {
|
|
212
|
+
bitmap_1 = parseBitmap(parsedData.d, parsedData.c);
|
|
224
213
|
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
214
|
+
catch (e) {
|
|
215
|
+
log.warn(STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2, ['BoundedFetchRequest', e]);
|
|
216
|
+
break;
|
|
217
|
+
}
|
|
218
|
+
forOwn(clients, function (_a, matchingKey) {
|
|
219
|
+
var hash64 = _a.hash64, worker = _a.worker, workerLarge = _a.workerLarge;
|
|
220
|
+
if (isInBitmap(bitmap_1, hash64.hex)) {
|
|
221
|
+
isLS ?
|
|
222
|
+
workerLarge && workerLarge.put(parsedData.changeNumber, undefined, getDelay(parsedData, matchingKey)) :
|
|
223
|
+
worker.put(parsedData.changeNumber);
|
|
235
224
|
}
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
225
|
+
});
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
case UpdateStrategy.KeyList: {
|
|
229
|
+
var keyList = void 0, added_1, removed_1;
|
|
230
|
+
try {
|
|
231
|
+
keyList = parseKeyList(parsedData.d, parsedData.c);
|
|
232
|
+
added_1 = new _Set(keyList.a);
|
|
233
|
+
removed_1 = new _Set(keyList.r);
|
|
234
|
+
}
|
|
235
|
+
catch (e) {
|
|
236
|
+
log.warn(STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2, ['KeyList', e]);
|
|
237
|
+
break;
|
|
238
|
+
}
|
|
239
|
+
forOwn(clients, function (_a) {
|
|
240
|
+
var hash64 = _a.hash64, worker = _a.worker, workerLarge = _a.workerLarge;
|
|
241
|
+
var add = added_1.has(hash64.dec) ? true : removed_1.has(hash64.dec) ? false : undefined;
|
|
242
|
+
if (add !== undefined) {
|
|
243
|
+
isLS ?
|
|
244
|
+
workerLarge && workerLarge.put(parsedData.changeNumber, {
|
|
245
|
+
name: parsedData.largeSegments[0],
|
|
246
|
+
add: add
|
|
247
|
+
}) :
|
|
240
248
|
worker.put(parsedData.changeNumber, {
|
|
241
249
|
name: parsedData.segmentName,
|
|
242
250
|
add: add
|
|
243
251
|
});
|
|
244
|
-
}
|
|
245
|
-
});
|
|
246
|
-
return;
|
|
247
|
-
}
|
|
248
|
-
case UpdateStrategy.SegmentRemoval:
|
|
249
|
-
if (!parsedData.segmentName) {
|
|
250
|
-
log.warn(STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2, ['SegmentRemoval', 'No segment name was provided']);
|
|
251
|
-
break;
|
|
252
252
|
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
253
|
+
});
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
case UpdateStrategy.SegmentRemoval:
|
|
257
|
+
if ((isLS && parsedData.largeSegments.length === 0) || (!isLS && !parsedData.segmentName)) {
|
|
258
|
+
log.warn(STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2, ['SegmentRemoval', 'No segment name was provided']);
|
|
259
|
+
break;
|
|
260
|
+
}
|
|
261
|
+
forOwn(clients, function (_a) {
|
|
262
|
+
var worker = _a.worker, workerLarge = _a.workerLarge;
|
|
263
|
+
isLS ?
|
|
264
|
+
workerLarge && parsedData.largeSegments.forEach(function (largeSegment) {
|
|
265
|
+
workerLarge.put(parsedData.changeNumber, {
|
|
266
|
+
name: largeSegment,
|
|
267
|
+
add: false
|
|
268
|
+
});
|
|
269
|
+
}) :
|
|
270
|
+
worker.put(parsedData.changeNumber, {
|
|
256
271
|
name: parsedData.segmentName,
|
|
257
272
|
add: false
|
|
258
273
|
});
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
274
|
+
});
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
// `UpdateStrategy.UnboundedFetchRequest` and fallbacks of other cases
|
|
278
|
+
forOwn(clients, function (_a, matchingKey) {
|
|
279
|
+
var worker = _a.worker, workerLarge = _a.workerLarge;
|
|
280
|
+
isLS ?
|
|
281
|
+
workerLarge && workerLarge.put(parsedData.changeNumber, undefined, getDelay(parsedData, matchingKey)) :
|
|
265
282
|
worker.put(parsedData.changeNumber);
|
|
266
|
-
});
|
|
267
283
|
});
|
|
268
284
|
}
|
|
285
|
+
if (userKey) {
|
|
286
|
+
pushEmitter.on(MY_SEGMENTS_UPDATE, function handleMySegmentsUpdate(parsedData, channel) {
|
|
287
|
+
var userKeyHash = channel.split('_')[2];
|
|
288
|
+
var userKey = userKeyHashes[userKeyHash];
|
|
289
|
+
if (userKey && clients[userKey]) { // check existence since it can be undefined if client has been destroyed
|
|
290
|
+
clients[userKey].worker.put(parsedData.changeNumber, parsedData.includesPayload ? parsedData.segmentList ? parsedData.segmentList : [] : undefined);
|
|
291
|
+
}
|
|
292
|
+
});
|
|
293
|
+
pushEmitter.on(MY_SEGMENTS_UPDATE_V2, handleMySegmentsUpdate);
|
|
294
|
+
pushEmitter.on(MY_LARGE_SEGMENTS_UPDATE, handleMySegmentsUpdate);
|
|
295
|
+
}
|
|
269
296
|
else {
|
|
270
297
|
pushEmitter.on(SEGMENT_UPDATE, segmentsUpdateWorker.put);
|
|
271
298
|
}
|
|
@@ -287,7 +314,7 @@ export function pushManagerFactory(params, pollingManager) {
|
|
|
287
314
|
return;
|
|
288
315
|
disconnected = false;
|
|
289
316
|
if (userKey)
|
|
290
|
-
this.add(userKey, pollingManager.segmentsSyncTask); // client-side
|
|
317
|
+
this.add(userKey, pollingManager.segmentsSyncTask, pollingManager.largeSegmentsSyncTask); // client-side
|
|
291
318
|
else
|
|
292
319
|
setTimeout(connectPush); // server-side runs in next cycle as in client-side, for consistency with client-side
|
|
293
320
|
},
|
|
@@ -296,11 +323,15 @@ export function pushManagerFactory(params, pollingManager) {
|
|
|
296
323
|
return disconnected === false;
|
|
297
324
|
},
|
|
298
325
|
// [Only for client-side]
|
|
299
|
-
add: function (userKey, mySegmentsSyncTask) {
|
|
326
|
+
add: function (userKey, mySegmentsSyncTask, myLargeSegmentsSyncTask) {
|
|
300
327
|
var hash = hashUserKey(userKey);
|
|
301
328
|
if (!userKeyHashes[hash]) {
|
|
302
329
|
userKeyHashes[hash] = userKey;
|
|
303
|
-
clients[userKey] = {
|
|
330
|
+
clients[userKey] = {
|
|
331
|
+
hash64: hash64(userKey),
|
|
332
|
+
worker: MySegmentsUpdateWorker(mySegmentsSyncTask, telemetryTracker, MY_SEGMENT),
|
|
333
|
+
workerLarge: myLargeSegmentsSyncTask ? MySegmentsUpdateWorker(myLargeSegmentsSyncTask, telemetryTracker, MY_LARGE_SEGMENT) : undefined
|
|
334
|
+
};
|
|
304
335
|
connectForNewClient = true; // we must reconnect on start, to listen the channel for the new user key
|
|
305
336
|
// Reconnects in case of a new client.
|
|
306
337
|
// Run in next event-loop cycle to save authentication calls
|
|
@@ -61,10 +61,12 @@ export function telemetryCacheConfigAdapter(telemetry, settings) {
|
|
|
61
61
|
var _a = getTelemetryFlagSetsStats(settings.sync.__splitFiltersValidation), flagSetsTotal = _a.flagSetsTotal, flagSetsIgnored = _a.flagSetsIgnored;
|
|
62
62
|
return objectAssign(getTelemetryConfigStats(settings.mode, settings.storage.type), {
|
|
63
63
|
sE: settings.streamingEnabled,
|
|
64
|
+
lE: isClientSide ? settings.sync.largeSegmentsEnabled : undefined,
|
|
64
65
|
rR: {
|
|
65
66
|
sp: scheduler.featuresRefreshRate / 1000,
|
|
66
67
|
se: isClientSide ? undefined : scheduler.segmentsRefreshRate / 1000,
|
|
67
68
|
ms: isClientSide ? scheduler.segmentsRefreshRate / 1000 : undefined,
|
|
69
|
+
mls: isClientSide && settings.sync.largeSegmentsEnabled ? scheduler.largeSegmentsRefreshRate / 1000 : undefined,
|
|
68
70
|
im: scheduler.impressionsRefreshRate / 1000,
|
|
69
71
|
ev: scheduler.eventsPushRate / 1000,
|
|
70
72
|
te: scheduler.telemetryRefreshRate / 1000,
|