@splitsoftware/splitio-commons 2.2.0 → 2.2.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 +3 -0
- package/README.md +1 -0
- package/cjs/evaluator/combiners/and.js +2 -6
- package/cjs/evaluator/combiners/ifelseif.js +6 -6
- package/cjs/evaluator/condition/index.js +6 -5
- package/cjs/evaluator/index.js +7 -7
- package/cjs/evaluator/matchers/index.js +3 -1
- package/cjs/evaluator/matchers/matcherTypes.js +1 -0
- package/cjs/evaluator/matchers/rbsegment.js +44 -0
- package/cjs/evaluator/matchersTransform/index.js +4 -0
- package/cjs/evaluator/parser/index.js +2 -2
- package/cjs/evaluator/value/sanitize.js +1 -0
- package/cjs/logger/constants.js +4 -3
- package/cjs/logger/messages/debug.js +3 -2
- package/cjs/logger/messages/warn.js +1 -1
- package/cjs/services/splitApi.js +3 -4
- package/cjs/storages/AbstractSplitsCacheSync.js +5 -2
- package/cjs/storages/KeyBuilder.js +9 -0
- package/cjs/storages/KeyBuilderCS.js +3 -0
- package/cjs/storages/KeyBuilderSS.js +3 -0
- package/cjs/storages/inLocalStorage/RBSegmentsCacheInLocal.js +117 -0
- package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +9 -14
- package/cjs/storages/inLocalStorage/index.js +5 -1
- package/cjs/storages/inLocalStorage/validateCache.js +2 -1
- package/cjs/storages/inMemory/InMemoryStorage.js +3 -0
- package/cjs/storages/inMemory/InMemoryStorageCS.js +4 -0
- package/cjs/storages/inMemory/RBSegmentsCacheInMemory.js +61 -0
- package/cjs/storages/inRedis/RBSegmentsCacheInRedis.js +64 -0
- package/cjs/storages/inRedis/index.js +2 -0
- package/cjs/storages/pluggable/RBSegmentsCachePluggable.js +64 -0
- package/cjs/storages/pluggable/index.js +2 -0
- package/cjs/sync/polling/fetchers/splitChangesFetcher.js +51 -4
- package/cjs/sync/polling/pollingManagerCS.js +7 -7
- package/cjs/sync/polling/syncTasks/splitsSyncTask.js +1 -1
- package/cjs/sync/polling/updaters/mySegmentsUpdater.js +2 -2
- package/cjs/sync/polling/updaters/segmentChangesUpdater.js +1 -1
- package/cjs/sync/polling/updaters/splitChangesUpdater.js +51 -33
- package/cjs/sync/streaming/SSEHandler/index.js +1 -0
- package/cjs/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +106 -77
- package/cjs/sync/streaming/constants.js +2 -1
- package/cjs/sync/streaming/pushManager.js +3 -16
- package/cjs/sync/syncManagerOnline.js +2 -2
- package/cjs/utils/constants/index.js +3 -2
- package/esm/evaluator/combiners/and.js +2 -6
- package/esm/evaluator/combiners/ifelseif.js +7 -7
- package/esm/evaluator/condition/index.js +6 -5
- package/esm/evaluator/index.js +7 -7
- package/esm/evaluator/matchers/index.js +3 -1
- package/esm/evaluator/matchers/matcherTypes.js +1 -0
- package/esm/evaluator/matchers/rbsegment.js +40 -0
- package/esm/evaluator/matchersTransform/index.js +4 -0
- package/esm/evaluator/parser/index.js +2 -2
- package/esm/evaluator/value/sanitize.js +1 -0
- package/esm/logger/constants.js +1 -0
- package/esm/logger/messages/debug.js +3 -2
- package/esm/logger/messages/warn.js +1 -1
- package/esm/services/splitApi.js +3 -4
- package/esm/storages/AbstractSplitsCacheSync.js +5 -2
- package/esm/storages/KeyBuilder.js +9 -0
- package/esm/storages/KeyBuilderCS.js +3 -0
- package/esm/storages/KeyBuilderSS.js +3 -0
- package/esm/storages/inLocalStorage/RBSegmentsCacheInLocal.js +114 -0
- package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +9 -14
- package/esm/storages/inLocalStorage/index.js +5 -1
- package/esm/storages/inLocalStorage/validateCache.js +2 -1
- package/esm/storages/inMemory/InMemoryStorage.js +3 -0
- package/esm/storages/inMemory/InMemoryStorageCS.js +4 -0
- package/esm/storages/inMemory/RBSegmentsCacheInMemory.js +58 -0
- package/esm/storages/inRedis/RBSegmentsCacheInRedis.js +61 -0
- package/esm/storages/inRedis/index.js +2 -0
- package/esm/storages/pluggable/RBSegmentsCachePluggable.js +61 -0
- package/esm/storages/pluggable/index.js +2 -0
- package/esm/sync/polling/fetchers/splitChangesFetcher.js +51 -4
- package/esm/sync/polling/pollingManagerCS.js +7 -7
- package/esm/sync/polling/syncTasks/splitsSyncTask.js +1 -1
- package/esm/sync/polling/updaters/mySegmentsUpdater.js +2 -2
- package/esm/sync/polling/updaters/segmentChangesUpdater.js +1 -1
- package/esm/sync/polling/updaters/splitChangesUpdater.js +51 -33
- package/esm/sync/streaming/SSEHandler/index.js +2 -1
- package/esm/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +102 -73
- package/esm/sync/streaming/constants.js +1 -0
- package/esm/sync/streaming/pushManager.js +6 -19
- package/esm/sync/syncManagerOnline.js +2 -2
- package/esm/utils/constants/index.js +2 -1
- package/package.json +1 -1
- package/src/dtos/types.ts +32 -8
- package/src/evaluator/Engine.ts +1 -1
- package/src/evaluator/combiners/and.ts +5 -4
- package/src/evaluator/combiners/ifelseif.ts +7 -9
- package/src/evaluator/condition/engineUtils.ts +1 -1
- package/src/evaluator/condition/index.ts +12 -12
- package/src/evaluator/index.ts +7 -7
- package/src/evaluator/matchers/index.ts +3 -1
- package/src/evaluator/matchers/matcherTypes.ts +1 -0
- package/src/evaluator/matchers/rbsegment.ts +62 -0
- package/src/evaluator/matchersTransform/index.ts +3 -0
- package/src/evaluator/parser/index.ts +3 -3
- package/src/evaluator/types.ts +2 -2
- package/src/evaluator/value/index.ts +2 -2
- package/src/evaluator/value/sanitize.ts +5 -4
- package/src/logger/constants.ts +1 -0
- package/src/logger/messages/debug.ts +3 -2
- package/src/logger/messages/warn.ts +1 -1
- package/src/sdkManager/index.ts +1 -1
- package/src/services/splitApi.ts +3 -4
- package/src/services/types.ts +1 -1
- package/src/storages/AbstractSplitsCacheSync.ts +6 -3
- package/src/storages/KeyBuilder.ts +12 -0
- package/src/storages/KeyBuilderCS.ts +4 -0
- package/src/storages/KeyBuilderSS.ts +4 -0
- package/src/storages/inLocalStorage/RBSegmentsCacheInLocal.ts +136 -0
- package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +10 -14
- package/src/storages/inLocalStorage/index.ts +5 -1
- package/src/storages/inLocalStorage/validateCache.ts +3 -1
- package/src/storages/inMemory/InMemoryStorage.ts +3 -0
- package/src/storages/inMemory/InMemoryStorageCS.ts +4 -0
- package/src/storages/inMemory/RBSegmentsCacheInMemory.ts +68 -0
- package/src/storages/inRedis/RBSegmentsCacheInRedis.ts +79 -0
- package/src/storages/inRedis/index.ts +2 -0
- package/src/storages/pluggable/RBSegmentsCachePluggable.ts +76 -0
- package/src/storages/pluggable/index.ts +2 -0
- package/src/storages/types.ts +33 -1
- package/src/sync/polling/fetchers/splitChangesFetcher.ts +62 -4
- package/src/sync/polling/fetchers/types.ts +1 -0
- package/src/sync/polling/pollingManagerCS.ts +7 -7
- package/src/sync/polling/syncTasks/splitsSyncTask.ts +1 -1
- package/src/sync/polling/types.ts +2 -2
- package/src/sync/polling/updaters/mySegmentsUpdater.ts +2 -2
- package/src/sync/polling/updaters/segmentChangesUpdater.ts +1 -1
- package/src/sync/polling/updaters/splitChangesUpdater.ts +61 -42
- package/src/sync/streaming/SSEHandler/index.ts +2 -1
- package/src/sync/streaming/SSEHandler/types.ts +2 -2
- package/src/sync/streaming/UpdateWorkers/SplitsUpdateWorker.ts +98 -68
- package/src/sync/streaming/constants.ts +1 -0
- package/src/sync/streaming/parseUtils.ts +2 -2
- package/src/sync/streaming/pushManager.ts +6 -18
- package/src/sync/streaming/types.ts +3 -2
- package/src/sync/syncManagerOnline.ts +2 -2
- package/src/utils/constants/index.ts +2 -1
- package/src/utils/lang/index.ts +1 -1
|
@@ -32,6 +32,9 @@ var KeyBuilderCS = /** @class */ (function (_super) {
|
|
|
32
32
|
KeyBuilderCS.prototype.isSplitKey = function (key) {
|
|
33
33
|
return startsWith(key, this.prefix + ".split.");
|
|
34
34
|
};
|
|
35
|
+
KeyBuilderCS.prototype.isRBSegmentKey = function (key) {
|
|
36
|
+
return startsWith(key, this.prefix + ".rbsegment.");
|
|
37
|
+
};
|
|
35
38
|
KeyBuilderCS.prototype.buildSplitsWithSegmentCountKey = function () {
|
|
36
39
|
return this.prefix + ".splits.usingSegments";
|
|
37
40
|
};
|
|
@@ -39,6 +39,9 @@ var KeyBuilderSS = /** @class */ (function (_super) {
|
|
|
39
39
|
KeyBuilderSS.prototype.searchPatternForSplitKeys = function () {
|
|
40
40
|
return this.buildSplitKeyPrefix() + "*";
|
|
41
41
|
};
|
|
42
|
+
KeyBuilderSS.prototype.searchPatternForRBSegmentKeys = function () {
|
|
43
|
+
return this.buildRBSegmentKeyPrefix() + "*";
|
|
44
|
+
};
|
|
42
45
|
/* Telemetry keys */
|
|
43
46
|
KeyBuilderSS.prototype.buildLatencyKey = function (method, bucket) {
|
|
44
47
|
return this.latencyPrefix + "::" + this.versionablePrefix + "/" + METHOD_NAMES[method] + "/" + bucket;
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { isFiniteNumber, isNaNNumber, toNumber } from '../../utils/lang';
|
|
2
|
+
import { setToArray } from '../../utils/lang/sets';
|
|
3
|
+
import { usesSegments } from '../AbstractSplitsCacheSync';
|
|
4
|
+
import { LOG_PREFIX } from './constants';
|
|
5
|
+
var RBSegmentsCacheInLocal = /** @class */ (function () {
|
|
6
|
+
function RBSegmentsCacheInLocal(settings, keys) {
|
|
7
|
+
this.keys = keys;
|
|
8
|
+
this.log = settings.log;
|
|
9
|
+
}
|
|
10
|
+
RBSegmentsCacheInLocal.prototype.clear = function () {
|
|
11
|
+
var _this = this;
|
|
12
|
+
this.getNames().forEach(function (name) { return _this.remove(name); });
|
|
13
|
+
localStorage.removeItem(this.keys.buildRBSegmentsTillKey());
|
|
14
|
+
};
|
|
15
|
+
RBSegmentsCacheInLocal.prototype.update = function (toAdd, toRemove, changeNumber) {
|
|
16
|
+
var _this = this;
|
|
17
|
+
this.setChangeNumber(changeNumber);
|
|
18
|
+
var updated = toAdd.map(function (toAdd) { return _this.add(toAdd); }).some(function (result) { return result; });
|
|
19
|
+
return toRemove.map(function (toRemove) { return _this.remove(toRemove.name); }).some(function (result) { return result; }) || updated;
|
|
20
|
+
};
|
|
21
|
+
RBSegmentsCacheInLocal.prototype.setChangeNumber = function (changeNumber) {
|
|
22
|
+
try {
|
|
23
|
+
localStorage.setItem(this.keys.buildRBSegmentsTillKey(), changeNumber + '');
|
|
24
|
+
localStorage.setItem(this.keys.buildLastUpdatedKey(), Date.now() + '');
|
|
25
|
+
}
|
|
26
|
+
catch (e) {
|
|
27
|
+
this.log.error(LOG_PREFIX + e);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
RBSegmentsCacheInLocal.prototype.updateSegmentCount = function (diff) {
|
|
31
|
+
var segmentsCountKey = this.keys.buildSplitsWithSegmentCountKey();
|
|
32
|
+
var count = toNumber(localStorage.getItem(segmentsCountKey)) + diff;
|
|
33
|
+
// @ts-expect-error
|
|
34
|
+
if (count > 0)
|
|
35
|
+
localStorage.setItem(segmentsCountKey, count);
|
|
36
|
+
else
|
|
37
|
+
localStorage.removeItem(segmentsCountKey);
|
|
38
|
+
};
|
|
39
|
+
RBSegmentsCacheInLocal.prototype.add = function (rbSegment) {
|
|
40
|
+
try {
|
|
41
|
+
var name_1 = rbSegment.name;
|
|
42
|
+
var rbSegmentKey = this.keys.buildRBSegmentKey(name_1);
|
|
43
|
+
var rbSegmentFromLocalStorage = localStorage.getItem(rbSegmentKey);
|
|
44
|
+
var previous = rbSegmentFromLocalStorage ? JSON.parse(rbSegmentFromLocalStorage) : null;
|
|
45
|
+
localStorage.setItem(rbSegmentKey, JSON.stringify(rbSegment));
|
|
46
|
+
var usesSegmentsDiff = 0;
|
|
47
|
+
if (previous && usesSegments(previous))
|
|
48
|
+
usesSegmentsDiff--;
|
|
49
|
+
if (usesSegments(rbSegment))
|
|
50
|
+
usesSegmentsDiff++;
|
|
51
|
+
if (usesSegmentsDiff !== 0)
|
|
52
|
+
this.updateSegmentCount(usesSegmentsDiff);
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
catch (e) {
|
|
56
|
+
this.log.error(LOG_PREFIX + e);
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
RBSegmentsCacheInLocal.prototype.remove = function (name) {
|
|
61
|
+
try {
|
|
62
|
+
var rbSegment = this.get(name);
|
|
63
|
+
if (!rbSegment)
|
|
64
|
+
return false;
|
|
65
|
+
localStorage.removeItem(this.keys.buildRBSegmentKey(name));
|
|
66
|
+
if (usesSegments(rbSegment))
|
|
67
|
+
this.updateSegmentCount(-1);
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
catch (e) {
|
|
71
|
+
this.log.error(LOG_PREFIX + e);
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
RBSegmentsCacheInLocal.prototype.getNames = function () {
|
|
76
|
+
var len = localStorage.length;
|
|
77
|
+
var accum = [];
|
|
78
|
+
var cur = 0;
|
|
79
|
+
while (cur < len) {
|
|
80
|
+
var key = localStorage.key(cur);
|
|
81
|
+
if (key != null && this.keys.isRBSegmentKey(key))
|
|
82
|
+
accum.push(this.keys.extractKey(key));
|
|
83
|
+
cur++;
|
|
84
|
+
}
|
|
85
|
+
return accum;
|
|
86
|
+
};
|
|
87
|
+
RBSegmentsCacheInLocal.prototype.get = function (name) {
|
|
88
|
+
var item = localStorage.getItem(this.keys.buildRBSegmentKey(name));
|
|
89
|
+
return item && JSON.parse(item);
|
|
90
|
+
};
|
|
91
|
+
RBSegmentsCacheInLocal.prototype.contains = function (names) {
|
|
92
|
+
var namesArray = setToArray(names);
|
|
93
|
+
var namesInStorage = this.getNames();
|
|
94
|
+
return namesArray.every(function (name) { return namesInStorage.indexOf(name) !== -1; });
|
|
95
|
+
};
|
|
96
|
+
RBSegmentsCacheInLocal.prototype.getChangeNumber = function () {
|
|
97
|
+
var n = -1;
|
|
98
|
+
var value = localStorage.getItem(this.keys.buildRBSegmentsTillKey());
|
|
99
|
+
if (value !== null) {
|
|
100
|
+
value = parseInt(value, 10);
|
|
101
|
+
return isNaNNumber(value) ? n : value;
|
|
102
|
+
}
|
|
103
|
+
return n;
|
|
104
|
+
};
|
|
105
|
+
RBSegmentsCacheInLocal.prototype.usesSegments = function () {
|
|
106
|
+
var storedCount = localStorage.getItem(this.keys.buildSplitsWithSegmentCountKey());
|
|
107
|
+
var splitsWithSegmentsCount = storedCount === null ? 0 : toNumber(storedCount);
|
|
108
|
+
return isFiniteNumber(splitsWithSegmentsCount) ?
|
|
109
|
+
splitsWithSegmentsCount > 0 :
|
|
110
|
+
true;
|
|
111
|
+
};
|
|
112
|
+
return RBSegmentsCacheInLocal;
|
|
113
|
+
}());
|
|
114
|
+
export { RBSegmentsCacheInLocal };
|
|
@@ -38,15 +38,13 @@ var SplitsCacheInLocal = /** @class */ (function (_super) {
|
|
|
38
38
|
};
|
|
39
39
|
SplitsCacheInLocal.prototype._incrementCounts = function (split) {
|
|
40
40
|
try {
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
var ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
|
|
42
|
+
// @ts-expect-error
|
|
43
|
+
localStorage.setItem(ttKey, toNumber(localStorage.getItem(ttKey)) + 1);
|
|
44
|
+
if (usesSegments(split)) {
|
|
45
|
+
var segmentsCountKey = this.keys.buildSplitsWithSegmentCountKey();
|
|
43
46
|
// @ts-expect-error
|
|
44
|
-
localStorage.setItem(
|
|
45
|
-
if (usesSegments(split)) {
|
|
46
|
-
var segmentsCountKey = this.keys.buildSplitsWithSegmentCountKey();
|
|
47
|
-
// @ts-expect-error
|
|
48
|
-
localStorage.setItem(segmentsCountKey, toNumber(localStorage.getItem(segmentsCountKey)) + 1);
|
|
49
|
-
}
|
|
47
|
+
localStorage.setItem(segmentsCountKey, toNumber(localStorage.getItem(segmentsCountKey)) + 1);
|
|
50
48
|
}
|
|
51
49
|
}
|
|
52
50
|
catch (e) {
|
|
@@ -155,12 +153,9 @@ var SplitsCacheInLocal = /** @class */ (function (_super) {
|
|
|
155
153
|
return true;
|
|
156
154
|
var storedCount = localStorage.getItem(this.keys.buildSplitsWithSegmentCountKey());
|
|
157
155
|
var splitsWithSegmentsCount = storedCount === null ? 0 : toNumber(storedCount);
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
else {
|
|
162
|
-
return true;
|
|
163
|
-
}
|
|
156
|
+
return isFiniteNumber(splitsWithSegmentsCount) ?
|
|
157
|
+
splitsWithSegmentsCount > 0 :
|
|
158
|
+
true;
|
|
164
159
|
};
|
|
165
160
|
SplitsCacheInLocal.prototype.getNamesByFlagSets = function (flagSets) {
|
|
166
161
|
var _this = this;
|
|
@@ -5,6 +5,7 @@ import { validatePrefix } from '../KeyBuilder';
|
|
|
5
5
|
import { KeyBuilderCS, myLargeSegmentsKeyBuilder } from '../KeyBuilderCS';
|
|
6
6
|
import { isLocalStorageAvailable } from '../../utils/env/isLocalStorageAvailable';
|
|
7
7
|
import { SplitsCacheInLocal } from './SplitsCacheInLocal';
|
|
8
|
+
import { RBSegmentsCacheInLocal } from './RBSegmentsCacheInLocal';
|
|
8
9
|
import { MySegmentsCacheInLocal } from './MySegmentsCacheInLocal';
|
|
9
10
|
import { InMemoryStorageCSFactory } from '../inMemory/InMemoryStorageCS';
|
|
10
11
|
import { LOG_PREFIX } from './constants';
|
|
@@ -29,10 +30,12 @@ export function InLocalStorage(options) {
|
|
|
29
30
|
var matchingKey = getMatching(settings.core.key);
|
|
30
31
|
var keys = new KeyBuilderCS(prefix, matchingKey);
|
|
31
32
|
var splits = new SplitsCacheInLocal(settings, keys);
|
|
33
|
+
var rbSegments = new RBSegmentsCacheInLocal(settings, keys);
|
|
32
34
|
var segments = new MySegmentsCacheInLocal(log, keys);
|
|
33
35
|
var largeSegments = new MySegmentsCacheInLocal(log, myLargeSegmentsKeyBuilder(prefix, matchingKey));
|
|
34
36
|
return {
|
|
35
37
|
splits: splits,
|
|
38
|
+
rbSegments: rbSegments,
|
|
36
39
|
segments: segments,
|
|
37
40
|
largeSegments: largeSegments,
|
|
38
41
|
impressions: new ImpressionsCacheInMemory(impressionsQueueSize),
|
|
@@ -41,13 +44,14 @@ export function InLocalStorage(options) {
|
|
|
41
44
|
telemetry: shouldRecordTelemetry(params) ? new TelemetryCacheInMemory(splits, segments) : undefined,
|
|
42
45
|
uniqueKeys: new UniqueKeysCacheInMemoryCS(),
|
|
43
46
|
validateCache: function () {
|
|
44
|
-
return validateCache(options, settings, keys, splits, segments, largeSegments);
|
|
47
|
+
return validateCache(options, settings, keys, splits, rbSegments, segments, largeSegments);
|
|
45
48
|
},
|
|
46
49
|
destroy: function () { },
|
|
47
50
|
// When using shared instantiation with MEMORY we reuse everything but segments (they are customer per key).
|
|
48
51
|
shared: function (matchingKey) {
|
|
49
52
|
return {
|
|
50
53
|
splits: this.splits,
|
|
54
|
+
rbSegments: this.rbSegments,
|
|
51
55
|
segments: new MySegmentsCacheInLocal(log, new KeyBuilderCS(prefix, matchingKey)),
|
|
52
56
|
largeSegments: new MySegmentsCacheInLocal(log, myLargeSegmentsKeyBuilder(prefix, matchingKey)),
|
|
53
57
|
impressions: this.impressions,
|
|
@@ -54,11 +54,12 @@ function validateExpiration(options, settings, keys, currentTimestamp, isThereCa
|
|
|
54
54
|
*
|
|
55
55
|
* @returns `true` if cache is ready to be used, `false` otherwise (cache was cleared or there is no cache)
|
|
56
56
|
*/
|
|
57
|
-
export function validateCache(options, settings, keys, splits, segments, largeSegments) {
|
|
57
|
+
export function validateCache(options, settings, keys, splits, rbSegments, segments, largeSegments) {
|
|
58
58
|
var currentTimestamp = Date.now();
|
|
59
59
|
var isThereCache = splits.getChangeNumber() > -1;
|
|
60
60
|
if (validateExpiration(options, settings, keys, currentTimestamp, isThereCache)) {
|
|
61
61
|
splits.clear();
|
|
62
|
+
rbSegments.clear();
|
|
62
63
|
segments.clear();
|
|
63
64
|
largeSegments.clear();
|
|
64
65
|
// Update last clear timestamp
|
|
@@ -6,6 +6,7 @@ import { ImpressionCountsCacheInMemory } from './ImpressionCountsCacheInMemory';
|
|
|
6
6
|
import { LOCALHOST_MODE, STORAGE_MEMORY } from '../../utils/constants';
|
|
7
7
|
import { shouldRecordTelemetry, TelemetryCacheInMemory } from './TelemetryCacheInMemory';
|
|
8
8
|
import { UniqueKeysCacheInMemory } from './UniqueKeysCacheInMemory';
|
|
9
|
+
import { RBSegmentsCacheInMemory } from './RBSegmentsCacheInMemory';
|
|
9
10
|
/**
|
|
10
11
|
* InMemory storage factory for standalone server-side SplitFactory
|
|
11
12
|
*
|
|
@@ -14,9 +15,11 @@ import { UniqueKeysCacheInMemory } from './UniqueKeysCacheInMemory';
|
|
|
14
15
|
export function InMemoryStorageFactory(params) {
|
|
15
16
|
var _a = params.settings, _b = _a.scheduler, impressionsQueueSize = _b.impressionsQueueSize, eventsQueueSize = _b.eventsQueueSize, __splitFiltersValidation = _a.sync.__splitFiltersValidation;
|
|
16
17
|
var splits = new SplitsCacheInMemory(__splitFiltersValidation);
|
|
18
|
+
var rbSegments = new RBSegmentsCacheInMemory();
|
|
17
19
|
var segments = new SegmentsCacheInMemory();
|
|
18
20
|
var storage = {
|
|
19
21
|
splits: splits,
|
|
22
|
+
rbSegments: rbSegments,
|
|
20
23
|
segments: segments,
|
|
21
24
|
impressions: new ImpressionsCacheInMemory(impressionsQueueSize),
|
|
22
25
|
impressionCounts: new ImpressionCountsCacheInMemory(),
|
|
@@ -6,6 +6,7 @@ import { ImpressionCountsCacheInMemory } from './ImpressionCountsCacheInMemory';
|
|
|
6
6
|
import { LOCALHOST_MODE, STORAGE_MEMORY } from '../../utils/constants';
|
|
7
7
|
import { shouldRecordTelemetry, TelemetryCacheInMemory } from './TelemetryCacheInMemory';
|
|
8
8
|
import { UniqueKeysCacheInMemoryCS } from './UniqueKeysCacheInMemoryCS';
|
|
9
|
+
import { RBSegmentsCacheInMemory } from './RBSegmentsCacheInMemory';
|
|
9
10
|
/**
|
|
10
11
|
* InMemory storage factory for standalone client-side SplitFactory
|
|
11
12
|
*
|
|
@@ -14,10 +15,12 @@ import { UniqueKeysCacheInMemoryCS } from './UniqueKeysCacheInMemoryCS';
|
|
|
14
15
|
export function InMemoryStorageCSFactory(params) {
|
|
15
16
|
var _a = params.settings, _b = _a.scheduler, impressionsQueueSize = _b.impressionsQueueSize, eventsQueueSize = _b.eventsQueueSize, __splitFiltersValidation = _a.sync.__splitFiltersValidation;
|
|
16
17
|
var splits = new SplitsCacheInMemory(__splitFiltersValidation);
|
|
18
|
+
var rbSegments = new RBSegmentsCacheInMemory();
|
|
17
19
|
var segments = new MySegmentsCacheInMemory();
|
|
18
20
|
var largeSegments = new MySegmentsCacheInMemory();
|
|
19
21
|
var storage = {
|
|
20
22
|
splits: splits,
|
|
23
|
+
rbSegments: rbSegments,
|
|
21
24
|
segments: segments,
|
|
22
25
|
largeSegments: largeSegments,
|
|
23
26
|
impressions: new ImpressionsCacheInMemory(impressionsQueueSize),
|
|
@@ -30,6 +33,7 @@ export function InMemoryStorageCSFactory(params) {
|
|
|
30
33
|
shared: function () {
|
|
31
34
|
return {
|
|
32
35
|
splits: this.splits,
|
|
36
|
+
rbSegments: this.rbSegments,
|
|
33
37
|
segments: new MySegmentsCacheInMemory(),
|
|
34
38
|
largeSegments: new MySegmentsCacheInMemory(),
|
|
35
39
|
impressions: this.impressions,
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { setToArray } from '../../utils/lang/sets';
|
|
2
|
+
import { usesSegments } from '../AbstractSplitsCacheSync';
|
|
3
|
+
var RBSegmentsCacheInMemory = /** @class */ (function () {
|
|
4
|
+
function RBSegmentsCacheInMemory() {
|
|
5
|
+
this.cache = {};
|
|
6
|
+
this.changeNumber = -1;
|
|
7
|
+
this.segmentsCount = 0;
|
|
8
|
+
}
|
|
9
|
+
RBSegmentsCacheInMemory.prototype.clear = function () {
|
|
10
|
+
this.cache = {};
|
|
11
|
+
this.changeNumber = -1;
|
|
12
|
+
this.segmentsCount = 0;
|
|
13
|
+
};
|
|
14
|
+
RBSegmentsCacheInMemory.prototype.update = function (toAdd, toRemove, changeNumber) {
|
|
15
|
+
var _this = this;
|
|
16
|
+
this.changeNumber = changeNumber;
|
|
17
|
+
var updated = toAdd.map(function (toAdd) { return _this.add(toAdd); }).some(function (result) { return result; });
|
|
18
|
+
return toRemove.map(function (toRemove) { return _this.remove(toRemove.name); }).some(function (result) { return result; }) || updated;
|
|
19
|
+
};
|
|
20
|
+
RBSegmentsCacheInMemory.prototype.add = function (rbSegment) {
|
|
21
|
+
var name = rbSegment.name;
|
|
22
|
+
var previous = this.get(name);
|
|
23
|
+
if (previous && usesSegments(previous))
|
|
24
|
+
this.segmentsCount--;
|
|
25
|
+
this.cache[name] = rbSegment;
|
|
26
|
+
if (usesSegments(rbSegment))
|
|
27
|
+
this.segmentsCount++;
|
|
28
|
+
return true;
|
|
29
|
+
};
|
|
30
|
+
RBSegmentsCacheInMemory.prototype.remove = function (name) {
|
|
31
|
+
var rbSegment = this.get(name);
|
|
32
|
+
if (!rbSegment)
|
|
33
|
+
return false;
|
|
34
|
+
delete this.cache[name];
|
|
35
|
+
if (usesSegments(rbSegment))
|
|
36
|
+
this.segmentsCount--;
|
|
37
|
+
return true;
|
|
38
|
+
};
|
|
39
|
+
RBSegmentsCacheInMemory.prototype.getNames = function () {
|
|
40
|
+
return Object.keys(this.cache);
|
|
41
|
+
};
|
|
42
|
+
RBSegmentsCacheInMemory.prototype.get = function (name) {
|
|
43
|
+
return this.cache[name] || null;
|
|
44
|
+
};
|
|
45
|
+
RBSegmentsCacheInMemory.prototype.contains = function (names) {
|
|
46
|
+
var namesArray = setToArray(names);
|
|
47
|
+
var namesInStorage = this.getNames();
|
|
48
|
+
return namesArray.every(function (name) { return namesInStorage.indexOf(name) !== -1; });
|
|
49
|
+
};
|
|
50
|
+
RBSegmentsCacheInMemory.prototype.getChangeNumber = function () {
|
|
51
|
+
return this.changeNumber;
|
|
52
|
+
};
|
|
53
|
+
RBSegmentsCacheInMemory.prototype.usesSegments = function () {
|
|
54
|
+
return this.segmentsCount > 0;
|
|
55
|
+
};
|
|
56
|
+
return RBSegmentsCacheInMemory;
|
|
57
|
+
}());
|
|
58
|
+
export { RBSegmentsCacheInMemory };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { isNaNNumber } from '../../utils/lang';
|
|
2
|
+
import { LOG_PREFIX } from './constants';
|
|
3
|
+
import { setToArray } from '../../utils/lang/sets';
|
|
4
|
+
var RBSegmentsCacheInRedis = /** @class */ (function () {
|
|
5
|
+
function RBSegmentsCacheInRedis(log, keys, redis) {
|
|
6
|
+
this.log = log;
|
|
7
|
+
this.keys = keys;
|
|
8
|
+
this.redis = redis;
|
|
9
|
+
}
|
|
10
|
+
RBSegmentsCacheInRedis.prototype.get = function (name) {
|
|
11
|
+
return this.redis.get(this.keys.buildRBSegmentKey(name))
|
|
12
|
+
.then(function (maybeRBSegment) { return maybeRBSegment && JSON.parse(maybeRBSegment); });
|
|
13
|
+
};
|
|
14
|
+
RBSegmentsCacheInRedis.prototype.getNames = function () {
|
|
15
|
+
var _this = this;
|
|
16
|
+
return this.redis.keys(this.keys.searchPatternForRBSegmentKeys()).then(function (listOfKeys) { return listOfKeys.map(_this.keys.extractKey); });
|
|
17
|
+
};
|
|
18
|
+
RBSegmentsCacheInRedis.prototype.contains = function (names) {
|
|
19
|
+
var namesArray = setToArray(names);
|
|
20
|
+
return this.getNames().then(function (namesInStorage) {
|
|
21
|
+
return namesArray.every(function (name) { return namesInStorage.includes(name); });
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
RBSegmentsCacheInRedis.prototype.update = function (toAdd, toRemove, changeNumber) {
|
|
25
|
+
var _this = this;
|
|
26
|
+
return Promise.all([
|
|
27
|
+
this.setChangeNumber(changeNumber),
|
|
28
|
+
Promise.all(toAdd.map(function (toAdd) {
|
|
29
|
+
var key = _this.keys.buildRBSegmentKey(toAdd.name);
|
|
30
|
+
var stringifiedNewRBSegment = JSON.stringify(toAdd);
|
|
31
|
+
return _this.redis.set(key, stringifiedNewRBSegment).then(function () { return true; });
|
|
32
|
+
})),
|
|
33
|
+
Promise.all(toRemove.map(function (toRemove) {
|
|
34
|
+
var key = _this.keys.buildRBSegmentKey(toRemove.name);
|
|
35
|
+
return _this.redis.del(key).then(function (status) { return status === 1; });
|
|
36
|
+
}))
|
|
37
|
+
]).then(function (_a) {
|
|
38
|
+
var added = _a[1], removed = _a[2];
|
|
39
|
+
return added.some(function (result) { return result; }) || removed.some(function (result) { return result; });
|
|
40
|
+
});
|
|
41
|
+
};
|
|
42
|
+
RBSegmentsCacheInRedis.prototype.setChangeNumber = function (changeNumber) {
|
|
43
|
+
return this.redis.set(this.keys.buildRBSegmentsTillKey(), changeNumber + '').then(function (status) { return status === 'OK'; });
|
|
44
|
+
};
|
|
45
|
+
RBSegmentsCacheInRedis.prototype.getChangeNumber = function () {
|
|
46
|
+
var _this = this;
|
|
47
|
+
return this.redis.get(this.keys.buildRBSegmentsTillKey()).then(function (value) {
|
|
48
|
+
var i = parseInt(value, 10);
|
|
49
|
+
return isNaNNumber(i) ? -1 : i;
|
|
50
|
+
}).catch(function (e) {
|
|
51
|
+
_this.log.error(LOG_PREFIX + 'Could not retrieve changeNumber from storage. Error: ' + e);
|
|
52
|
+
return -1;
|
|
53
|
+
});
|
|
54
|
+
};
|
|
55
|
+
// @TODO implement if required by DataLoader or producer mode
|
|
56
|
+
RBSegmentsCacheInRedis.prototype.clear = function () {
|
|
57
|
+
return Promise.resolve();
|
|
58
|
+
};
|
|
59
|
+
return RBSegmentsCacheInRedis;
|
|
60
|
+
}());
|
|
61
|
+
export { RBSegmentsCacheInRedis };
|
|
@@ -9,6 +9,7 @@ import { TelemetryCacheInRedis } from './TelemetryCacheInRedis';
|
|
|
9
9
|
import { UniqueKeysCacheInRedis } from './UniqueKeysCacheInRedis';
|
|
10
10
|
import { ImpressionCountsCacheInRedis } from './ImpressionCountsCacheInRedis';
|
|
11
11
|
import { metadataBuilder } from '../utils';
|
|
12
|
+
import { RBSegmentsCacheInRedis } from './RBSegmentsCacheInRedis';
|
|
12
13
|
/**
|
|
13
14
|
* InRedis storage factory for consumer server-side SplitFactory, that uses `Ioredis` Redis client for Node.js
|
|
14
15
|
* @see {@link https://www.npmjs.com/package/ioredis}
|
|
@@ -37,6 +38,7 @@ export function InRedisStorage(options) {
|
|
|
37
38
|
});
|
|
38
39
|
return {
|
|
39
40
|
splits: new SplitsCacheInRedis(log, keys, redisClient, settings.sync.__splitFiltersValidation),
|
|
41
|
+
rbSegments: new RBSegmentsCacheInRedis(log, keys, redisClient),
|
|
40
42
|
segments: new SegmentsCacheInRedis(log, keys, redisClient),
|
|
41
43
|
impressions: new ImpressionsCacheInRedis(log, keys.buildImpressionsKey(), redisClient, metadata),
|
|
42
44
|
impressionCounts: impressionCountsCache,
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { isNaNNumber } from '../../utils/lang';
|
|
2
|
+
import { LOG_PREFIX } from './constants';
|
|
3
|
+
import { setToArray } from '../../utils/lang/sets';
|
|
4
|
+
var RBSegmentsCachePluggable = /** @class */ (function () {
|
|
5
|
+
function RBSegmentsCachePluggable(log, keys, wrapper) {
|
|
6
|
+
this.log = log;
|
|
7
|
+
this.keys = keys;
|
|
8
|
+
this.wrapper = wrapper;
|
|
9
|
+
}
|
|
10
|
+
RBSegmentsCachePluggable.prototype.get = function (name) {
|
|
11
|
+
return this.wrapper.get(this.keys.buildRBSegmentKey(name))
|
|
12
|
+
.then(function (maybeRBSegment) { return maybeRBSegment && JSON.parse(maybeRBSegment); });
|
|
13
|
+
};
|
|
14
|
+
RBSegmentsCachePluggable.prototype.getNames = function () {
|
|
15
|
+
var _this = this;
|
|
16
|
+
return this.wrapper.getKeysByPrefix(this.keys.buildRBSegmentKeyPrefix()).then(function (listOfKeys) { return listOfKeys.map(_this.keys.extractKey); });
|
|
17
|
+
};
|
|
18
|
+
RBSegmentsCachePluggable.prototype.contains = function (names) {
|
|
19
|
+
var namesArray = setToArray(names);
|
|
20
|
+
return this.getNames().then(function (namesInStorage) {
|
|
21
|
+
return namesArray.every(function (name) { return namesInStorage.includes(name); });
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
RBSegmentsCachePluggable.prototype.update = function (toAdd, toRemove, changeNumber) {
|
|
25
|
+
var _this = this;
|
|
26
|
+
return Promise.all([
|
|
27
|
+
this.setChangeNumber(changeNumber),
|
|
28
|
+
Promise.all(toAdd.map(function (toAdd) {
|
|
29
|
+
var key = _this.keys.buildRBSegmentKey(toAdd.name);
|
|
30
|
+
var stringifiedNewRBSegment = JSON.stringify(toAdd);
|
|
31
|
+
return _this.wrapper.set(key, stringifiedNewRBSegment).then(function () { return true; });
|
|
32
|
+
})),
|
|
33
|
+
Promise.all(toRemove.map(function (toRemove) {
|
|
34
|
+
var key = _this.keys.buildRBSegmentKey(toRemove.name);
|
|
35
|
+
return _this.wrapper.del(key);
|
|
36
|
+
}))
|
|
37
|
+
]).then(function (_a) {
|
|
38
|
+
var added = _a[1], removed = _a[2];
|
|
39
|
+
return added.some(function (result) { return result; }) || removed.some(function (result) { return result; });
|
|
40
|
+
});
|
|
41
|
+
};
|
|
42
|
+
RBSegmentsCachePluggable.prototype.setChangeNumber = function (changeNumber) {
|
|
43
|
+
return this.wrapper.set(this.keys.buildRBSegmentsTillKey(), changeNumber + '');
|
|
44
|
+
};
|
|
45
|
+
RBSegmentsCachePluggable.prototype.getChangeNumber = function () {
|
|
46
|
+
var _this = this;
|
|
47
|
+
return this.wrapper.get(this.keys.buildRBSegmentsTillKey()).then(function (value) {
|
|
48
|
+
var i = parseInt(value, 10);
|
|
49
|
+
return isNaNNumber(i) ? -1 : i;
|
|
50
|
+
}).catch(function (e) {
|
|
51
|
+
_this.log.error(LOG_PREFIX + 'Could not retrieve changeNumber from storage. Error: ' + e);
|
|
52
|
+
return -1;
|
|
53
|
+
});
|
|
54
|
+
};
|
|
55
|
+
// @TODO implement if required by DataLoader or producer mode
|
|
56
|
+
RBSegmentsCachePluggable.prototype.clear = function () {
|
|
57
|
+
return Promise.resolve();
|
|
58
|
+
};
|
|
59
|
+
return RBSegmentsCachePluggable;
|
|
60
|
+
}());
|
|
61
|
+
export { RBSegmentsCachePluggable };
|
|
@@ -19,6 +19,7 @@ import { UniqueKeysCacheInMemory } from '../inMemory/UniqueKeysCacheInMemory';
|
|
|
19
19
|
import { UniqueKeysCacheInMemoryCS } from '../inMemory/UniqueKeysCacheInMemoryCS';
|
|
20
20
|
import { metadataBuilder } from '../utils';
|
|
21
21
|
import { LOG_PREFIX } from '../pluggable/constants';
|
|
22
|
+
import { RBSegmentsCachePluggable } from './RBSegmentsCachePluggable';
|
|
22
23
|
var NO_VALID_WRAPPER = 'Expecting pluggable storage `wrapper` in options, but no valid wrapper instance was provided.';
|
|
23
24
|
var NO_VALID_WRAPPER_INTERFACE = 'The provided wrapper instance doesn’t follow the expected interface. Check our docs.';
|
|
24
25
|
/**
|
|
@@ -102,6 +103,7 @@ export function PluggableStorage(options) {
|
|
|
102
103
|
});
|
|
103
104
|
return {
|
|
104
105
|
splits: new SplitsCachePluggable(log, keys, wrapper, settings.sync.__splitFiltersValidation),
|
|
106
|
+
rbSegments: new RBSegmentsCachePluggable(log, keys, wrapper),
|
|
105
107
|
segments: new SegmentsCachePluggable(log, keys, wrapper),
|
|
106
108
|
impressions: isPartialConsumer ? new ImpressionsCacheInMemory(impressionsQueueSize) : new ImpressionsCachePluggable(log, keys.buildImpressionsKey(), wrapper, metadata),
|
|
107
109
|
impressionCounts: impressionCountsCache,
|
|
@@ -1,14 +1,61 @@
|
|
|
1
|
+
import { FLAG_SPEC_VERSION } from '../../../utils/constants';
|
|
2
|
+
import { base } from '../../../utils/settingsValidation';
|
|
3
|
+
import { LOG_PREFIX_SYNC_SPLITS } from '../../../logger/constants';
|
|
4
|
+
var PROXY_CHECK_INTERVAL_MILLIS_CS = 60 * 60 * 1000; // 1 hour in Client Side
|
|
5
|
+
var PROXY_CHECK_INTERVAL_MILLIS_SS = 24 * PROXY_CHECK_INTERVAL_MILLIS_CS; // 24 hours in Server Side
|
|
6
|
+
function sdkEndpointOverriden(settings) {
|
|
7
|
+
return settings.urls.sdk !== base.urls.sdk;
|
|
8
|
+
}
|
|
1
9
|
/**
|
|
2
10
|
* Factory of SplitChanges fetcher.
|
|
3
11
|
* SplitChanges fetcher is a wrapper around `splitChanges` API service that parses the response and handle errors.
|
|
4
12
|
*/
|
|
5
|
-
|
|
6
|
-
|
|
13
|
+
// @TODO breaking: drop support for Split Proxy below v5.10.0 and simplify the implementation
|
|
14
|
+
export function splitChangesFetcherFactory(fetchSplitChanges, settings, storage) {
|
|
15
|
+
var log = settings.log;
|
|
16
|
+
var PROXY_CHECK_INTERVAL_MILLIS = settings.core.key !== undefined ? PROXY_CHECK_INTERVAL_MILLIS_CS : PROXY_CHECK_INTERVAL_MILLIS_SS;
|
|
17
|
+
var lastProxyCheckTimestamp;
|
|
18
|
+
return function splitChangesFetcher(since, noCache, till, rbSince,
|
|
7
19
|
// Optional decorator for `fetchSplitChanges` promise, such as timeout or time tracker
|
|
8
20
|
decorator) {
|
|
9
|
-
|
|
21
|
+
// Recheck proxy
|
|
22
|
+
if (lastProxyCheckTimestamp && (Date.now() - lastProxyCheckTimestamp) > PROXY_CHECK_INTERVAL_MILLIS) {
|
|
23
|
+
settings.sync.flagSpecVersion = FLAG_SPEC_VERSION;
|
|
24
|
+
}
|
|
25
|
+
var splitsPromise = fetchSplitChanges(since, noCache, till, settings.sync.flagSpecVersion === FLAG_SPEC_VERSION ? rbSince : undefined)
|
|
26
|
+
// Handle proxy error with spec 1.3
|
|
27
|
+
.catch(function (err) {
|
|
28
|
+
if (err.statusCode === 400 && sdkEndpointOverriden(settings) && settings.sync.flagSpecVersion === FLAG_SPEC_VERSION) {
|
|
29
|
+
log.error(LOG_PREFIX_SYNC_SPLITS + 'Proxy error detected. If you are using Split Proxy, please upgrade to latest version');
|
|
30
|
+
lastProxyCheckTimestamp = Date.now();
|
|
31
|
+
settings.sync.flagSpecVersion = '1.2'; // fallback to 1.2 spec
|
|
32
|
+
return fetchSplitChanges(since, noCache, till); // retry request without rbSince
|
|
33
|
+
}
|
|
34
|
+
throw err;
|
|
35
|
+
});
|
|
10
36
|
if (decorator)
|
|
11
37
|
splitsPromise = decorator(splitsPromise);
|
|
12
|
-
return splitsPromise
|
|
38
|
+
return splitsPromise
|
|
39
|
+
.then(function (resp) { return resp.json(); })
|
|
40
|
+
.then(function (data) {
|
|
41
|
+
// Using flag spec version 1.2
|
|
42
|
+
if (data.splits) {
|
|
43
|
+
return {
|
|
44
|
+
ff: {
|
|
45
|
+
d: data.splits,
|
|
46
|
+
s: data.since,
|
|
47
|
+
t: data.till
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
// Proxy recovery
|
|
52
|
+
if (lastProxyCheckTimestamp) {
|
|
53
|
+
log.info(LOG_PREFIX_SYNC_SPLITS + 'Proxy error recovered');
|
|
54
|
+
lastProxyCheckTimestamp = undefined;
|
|
55
|
+
return Promise.all([storage.splits.clear(), storage.rbSegments.clear()])
|
|
56
|
+
.then(function () { return splitChangesFetcher(storage.splits.getChangeNumber(), undefined, undefined, storage.rbSegments.getChangeNumber()); });
|
|
57
|
+
}
|
|
58
|
+
return data;
|
|
59
|
+
});
|
|
13
60
|
};
|
|
14
61
|
}
|
|
@@ -31,10 +31,10 @@ export function pollingManagerCSFactory(params) {
|
|
|
31
31
|
readiness.splits.on(SDK_SPLITS_ARRIVED, function () {
|
|
32
32
|
if (!splitsSyncTask.isRunning())
|
|
33
33
|
return; // noop if not doing polling
|
|
34
|
-
var
|
|
35
|
-
if (
|
|
36
|
-
log.info(POLLING_SMART_PAUSING, [
|
|
37
|
-
if (
|
|
34
|
+
var usingSegments = storage.splits.usesSegments() || storage.rbSegments.usesSegments();
|
|
35
|
+
if (usingSegments !== mySegmentsSyncTask.isRunning()) {
|
|
36
|
+
log.info(POLLING_SMART_PAUSING, [usingSegments ? 'ON' : 'OFF']);
|
|
37
|
+
if (usingSegments) {
|
|
38
38
|
startMySegmentsSyncTasks();
|
|
39
39
|
}
|
|
40
40
|
else {
|
|
@@ -46,10 +46,10 @@ export function pollingManagerCSFactory(params) {
|
|
|
46
46
|
var mySegmentsSyncTask = mySegmentsSyncTaskFactory(splitApi.fetchMemberships, storage, readiness, settings, matchingKey);
|
|
47
47
|
// smart ready
|
|
48
48
|
function smartReady() {
|
|
49
|
-
if (!readiness.isReady() && !storage.splits.usesSegments())
|
|
49
|
+
if (!readiness.isReady() && !storage.splits.usesSegments() && !storage.rbSegments.usesSegments())
|
|
50
50
|
readiness.segments.emit(SDK_SEGMENTS_ARRIVED);
|
|
51
51
|
}
|
|
52
|
-
if (!storage.splits.usesSegments())
|
|
52
|
+
if (!storage.splits.usesSegments() && !storage.rbSegments.usesSegments())
|
|
53
53
|
setTimeout(smartReady, 0);
|
|
54
54
|
else
|
|
55
55
|
readiness.splits.once(SDK_SPLITS_ARRIVED, smartReady);
|
|
@@ -63,7 +63,7 @@ export function pollingManagerCSFactory(params) {
|
|
|
63
63
|
start: function () {
|
|
64
64
|
log.info(POLLING_START);
|
|
65
65
|
splitsSyncTask.start();
|
|
66
|
-
if (storage.splits.usesSegments())
|
|
66
|
+
if (storage.splits.usesSegments() || storage.rbSegments.usesSegments())
|
|
67
67
|
startMySegmentsSyncTasks();
|
|
68
68
|
},
|
|
69
69
|
// Stop periodic fetching (polling)
|
|
@@ -5,5 +5,5 @@ import { splitChangesUpdaterFactory } from '../updaters/splitChangesUpdater';
|
|
|
5
5
|
* Creates a sync task that periodically executes a `splitChangesUpdater` task
|
|
6
6
|
*/
|
|
7
7
|
export function splitsSyncTaskFactory(fetchSplitChanges, storage, readiness, settings, isClientSide) {
|
|
8
|
-
return syncTaskFactory(settings.log, splitChangesUpdaterFactory(settings.log, splitChangesFetcherFactory(fetchSplitChanges), storage, settings.sync.__splitFiltersValidation, readiness.splits, settings.startup.requestTimeoutBeforeReady, settings.startup.retriesOnFailureBeforeReady, isClientSide), settings.scheduler.featuresRefreshRate, 'splitChangesUpdater');
|
|
8
|
+
return syncTaskFactory(settings.log, splitChangesUpdaterFactory(settings.log, splitChangesFetcherFactory(fetchSplitChanges, settings, storage), storage, settings.sync.__splitFiltersValidation, readiness.splits, settings.startup.requestTimeoutBeforeReady, settings.startup.retriesOnFailureBeforeReady, isClientSide), settings.scheduler.featuresRefreshRate, 'splitChangesUpdater');
|
|
9
9
|
}
|
|
@@ -9,7 +9,7 @@ import { MEMBERSHIPS_LS_UPDATE } from '../../streaming/constants';
|
|
|
9
9
|
* - uses `segmentsEventEmitter` to emit events related to segments data updates
|
|
10
10
|
*/
|
|
11
11
|
export function mySegmentsUpdaterFactory(log, mySegmentsFetcher, storage, segmentsEventEmitter, requestTimeoutBeforeReady, retriesOnFailureBeforeReady, matchingKey) {
|
|
12
|
-
var splits = storage.splits, segments = storage.segments, largeSegments = storage.largeSegments;
|
|
12
|
+
var splits = storage.splits, rbSegments = storage.rbSegments, segments = storage.segments, largeSegments = storage.largeSegments;
|
|
13
13
|
var readyOnAlreadyExistentState = true;
|
|
14
14
|
var startingUp = true;
|
|
15
15
|
/** timeout and telemetry decorator for `splitChangesFetcher` promise */
|
|
@@ -31,7 +31,7 @@ export function mySegmentsUpdaterFactory(log, mySegmentsFetcher, storage, segmen
|
|
|
31
31
|
shouldNotifyUpdate = largeSegments.resetSegments(segmentsData.ls || {}) || shouldNotifyUpdate;
|
|
32
32
|
}
|
|
33
33
|
// Notify update if required
|
|
34
|
-
if (splits.usesSegments() && (shouldNotifyUpdate || readyOnAlreadyExistentState)) {
|
|
34
|
+
if ((splits.usesSegments() || rbSegments.usesSegments()) && (shouldNotifyUpdate || readyOnAlreadyExistentState)) {
|
|
35
35
|
readyOnAlreadyExistentState = false;
|
|
36
36
|
segmentsEventEmitter.emit(SDK_SEGMENTS_ARRIVED);
|
|
37
37
|
}
|
|
@@ -36,7 +36,7 @@ export function segmentChangesUpdaterFactory(log, segmentChangesFetcher, segment
|
|
|
36
36
|
* Returned promise will not be rejected.
|
|
37
37
|
*
|
|
38
38
|
* @param fetchOnlyNew - if true, only fetch the segments that not exists, i.e., which `changeNumber` is equal to -1.
|
|
39
|
-
* This param is used by SplitUpdateWorker on server-side SDK, to fetch new registered segments on SPLIT_UPDATE notifications.
|
|
39
|
+
* This param is used by SplitUpdateWorker on server-side SDK, to fetch new registered segments on SPLIT_UPDATE or RB_SEGMENT_UPDATE notifications.
|
|
40
40
|
* @param segmentName - segment name to fetch. By passing `undefined` it fetches the list of segments registered at the storage
|
|
41
41
|
* @param noCache - true to revalidate data to fetch on a SEGMENT_UPDATE notifications.
|
|
42
42
|
* @param till - till target for the provided segmentName, for CDN bypass.
|