@splitsoftware/splitio-commons 1.16.1-rc.1 → 1.16.1-rc.11
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 +4 -0
- package/cjs/logger/constants.js +5 -4
- package/cjs/logger/messages/info.js +2 -1
- package/cjs/logger/messages/warn.js +1 -1
- package/cjs/readiness/readinessManager.js +7 -12
- package/cjs/services/splitApi.js +5 -9
- package/cjs/storages/AbstractSegmentsCacheSync.js +41 -12
- package/cjs/storages/AbstractSplitsCacheAsync.js +2 -2
- package/cjs/storages/AbstractSplitsCacheSync.js +7 -5
- package/cjs/storages/KeyBuilder.js +0 -3
- package/cjs/storages/KeyBuilderCS.js +6 -0
- package/cjs/storages/dataLoader.js +1 -1
- package/cjs/storages/inLocalStorage/MySegmentsCacheInLocal.js +29 -52
- package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +4 -16
- package/cjs/storages/inMemory/MySegmentsCacheInMemory.js +9 -40
- package/cjs/storages/inMemory/SplitsCacheInMemory.js +6 -15
- package/cjs/sync/polling/fetchers/mySegmentsFetcher.js +4 -11
- package/cjs/sync/polling/fetchers/segmentChangesFetcher.js +1 -1
- package/cjs/sync/polling/pollingManagerCS.js +33 -51
- package/cjs/sync/polling/syncTasks/mySegmentsSyncTask.js +2 -2
- package/cjs/sync/polling/updaters/mySegmentsUpdater.js +14 -20
- package/cjs/sync/streaming/AuthClient/index.js +1 -1
- package/cjs/sync/streaming/SSEHandler/index.js +3 -6
- package/cjs/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +15 -9
- package/cjs/sync/streaming/constants.js +3 -4
- package/cjs/sync/streaming/parseUtils.js +14 -9
- package/cjs/sync/streaming/pushManager.js +29 -55
- package/cjs/sync/submitters/telemetrySubmitter.js +0 -2
- package/cjs/sync/syncManagerOnline.js +14 -24
- package/cjs/utils/constants/index.js +4 -5
- package/cjs/utils/settingsValidation/index.js +1 -5
- package/esm/logger/constants.js +2 -1
- package/esm/logger/messages/info.js +2 -1
- package/esm/logger/messages/warn.js +1 -1
- package/esm/readiness/readinessManager.js +7 -12
- package/esm/services/splitApi.js +6 -10
- package/esm/storages/AbstractSegmentsCacheSync.js +41 -12
- package/esm/storages/AbstractSplitsCacheAsync.js +2 -2
- package/esm/storages/AbstractSplitsCacheSync.js +5 -3
- package/esm/storages/KeyBuilder.js +0 -3
- package/esm/storages/KeyBuilderCS.js +6 -0
- package/esm/storages/dataLoader.js +1 -1
- package/esm/storages/inLocalStorage/MySegmentsCacheInLocal.js +29 -52
- package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +5 -17
- package/esm/storages/inMemory/MySegmentsCacheInMemory.js +9 -40
- package/esm/storages/inMemory/SplitsCacheInMemory.js +7 -16
- package/esm/sync/polling/fetchers/mySegmentsFetcher.js +4 -11
- package/esm/sync/polling/fetchers/segmentChangesFetcher.js +1 -1
- package/esm/sync/polling/pollingManagerCS.js +34 -52
- package/esm/sync/polling/syncTasks/mySegmentsSyncTask.js +2 -2
- package/esm/sync/polling/updaters/mySegmentsUpdater.js +12 -18
- package/esm/sync/streaming/AuthClient/index.js +1 -1
- package/esm/sync/streaming/SSEHandler/index.js +4 -7
- package/esm/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +15 -9
- package/esm/sync/streaming/constants.js +2 -3
- package/esm/sync/streaming/parseUtils.js +12 -8
- package/esm/sync/streaming/pushManager.js +32 -57
- package/esm/sync/submitters/telemetrySubmitter.js +0 -2
- package/esm/sync/syncManagerOnline.js +15 -25
- package/esm/utils/constants/index.js +2 -3
- package/esm/utils/settingsValidation/index.js +1 -5
- package/package.json +1 -1
- package/src/dtos/types.ts +7 -8
- package/src/logger/constants.ts +2 -1
- package/src/logger/messages/info.ts +2 -1
- package/src/logger/messages/warn.ts +1 -1
- package/src/readiness/readinessManager.ts +7 -9
- package/src/readiness/types.ts +0 -1
- package/src/services/splitApi.ts +7 -12
- package/src/services/splitHttpClient.ts +1 -1
- package/src/services/types.ts +2 -3
- package/src/storages/AbstractSegmentsCacheSync.ts +53 -12
- package/src/storages/AbstractSplitsCacheAsync.ts +2 -2
- package/src/storages/AbstractSplitsCacheSync.ts +7 -5
- package/src/storages/KeyBuilder.ts +0 -3
- package/src/storages/KeyBuilderCS.ts +9 -0
- package/src/storages/dataLoader.ts +1 -1
- package/src/storages/inLocalStorage/MySegmentsCacheInLocal.ts +26 -56
- package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +5 -20
- package/src/storages/inMemory/MySegmentsCacheInMemory.ts +10 -44
- package/src/storages/inMemory/SplitsCacheInMemory.ts +7 -13
- package/src/storages/types.ts +10 -8
- package/src/sync/polling/fetchers/mySegmentsFetcher.ts +7 -14
- package/src/sync/polling/fetchers/segmentChangesFetcher.ts +1 -1
- package/src/sync/polling/fetchers/types.ts +2 -2
- package/src/sync/polling/pollingManagerCS.ts +29 -61
- package/src/sync/polling/syncTasks/mySegmentsSyncTask.ts +12 -13
- package/src/sync/polling/types.ts +8 -8
- package/src/sync/polling/updaters/mySegmentsUpdater.ts +17 -18
- package/src/sync/streaming/AuthClient/index.ts +1 -1
- package/src/sync/streaming/SSEClient/index.ts +4 -6
- package/src/sync/streaming/SSEHandler/index.ts +5 -9
- package/src/sync/streaming/SSEHandler/types.ts +13 -25
- package/src/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.ts +17 -12
- package/src/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.ts +1 -1
- package/src/sync/streaming/UpdateWorkers/SplitsUpdateWorker.ts +1 -1
- package/src/sync/streaming/UpdateWorkers/types.ts +2 -2
- package/src/sync/streaming/constants.ts +2 -3
- package/src/sync/streaming/parseUtils.ts +19 -11
- package/src/sync/streaming/pushManager.ts +38 -68
- package/src/sync/streaming/types.ts +11 -13
- package/src/sync/submitters/telemetrySubmitter.ts +0 -2
- package/src/sync/submitters/types.ts +3 -6
- package/src/sync/syncManagerOnline.ts +11 -19
- package/src/types.ts +1 -26
- package/src/utils/constants/index.ts +2 -3
- package/src/utils/settingsValidation/index.ts +1 -5
- package/types/dtos/types.d.ts +7 -8
- package/types/logger/constants.d.ts +2 -1
- package/types/readiness/types.d.ts +0 -1
- package/types/services/decorateHeaders.d.ts +2 -0
- package/types/services/splitApi.d.ts +1 -1
- package/types/services/splitHttpClient.d.ts +1 -1
- package/types/services/types.d.ts +2 -3
- package/types/storages/AbstractSegmentsCacheSync.d.ts +9 -11
- package/types/storages/AbstractSplitsCacheAsync.d.ts +1 -1
- package/types/storages/AbstractSplitsCacheSync.d.ts +4 -4
- package/types/storages/KeyBuilder.d.ts +0 -1
- package/types/storages/KeyBuilderCS.d.ts +2 -0
- package/types/storages/inLocalStorage/MySegmentsCacheInLocal.d.ts +2 -12
- package/types/storages/inLocalStorage/SplitsCacheInLocal.d.ts +1 -1
- package/types/storages/inMemory/MySegmentsCacheInMemory.d.ts +3 -9
- package/types/storages/inMemory/SplitsCacheInMemory.d.ts +1 -2
- package/types/storages/types.d.ts +8 -7
- package/types/sync/polling/fetchers/mySegmentsFetcher.d.ts +2 -2
- package/types/sync/polling/fetchers/types.d.ts +2 -2
- package/types/sync/polling/syncTasks/mySegmentsSyncTask.d.ts +4 -3
- package/types/sync/polling/types.d.ts +8 -12
- package/types/sync/polling/updaters/mySegmentsUpdater.d.ts +3 -2
- package/types/sync/streaming/SSEHandler/types.d.ts +13 -22
- package/types/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.d.ts +2 -3
- package/types/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.d.ts +2 -1
- package/types/sync/streaming/UpdateWorkers/SplitsUpdateWorker.d.ts +3 -2
- package/types/sync/streaming/UpdateWorkers/types.d.ts +2 -2
- package/types/sync/streaming/constants.d.ts +2 -3
- package/types/sync/streaming/parseUtils.d.ts +4 -5
- package/types/sync/streaming/pushManager.d.ts +0 -2
- package/types/sync/streaming/pushManagerCS_Spec1_3.d.ts +9 -0
- package/types/sync/streaming/pushManager_Spec1_3.d.ts +9 -0
- package/types/sync/streaming/types.d.ts +9 -10
- package/types/sync/submitters/types.d.ts +3 -6
- package/types/types.d.ts +0 -25
- package/types/utils/constants/index.d.ts +2 -3
- package/types/utils/settingsValidation/index.d.ts +0 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.pushManagerFactory =
|
|
3
|
+
exports.pushManagerFactory = void 0;
|
|
4
4
|
var objectAssign_1 = require("../../utils/lang/objectAssign");
|
|
5
5
|
var Backoff_1 = require("../../utils/Backoff");
|
|
6
6
|
var SSEHandler_1 = require("./SSEHandler");
|
|
@@ -16,15 +16,8 @@ var constants_2 = require("../../logger/constants");
|
|
|
16
16
|
var types_1 = require("./SSEHandler/types");
|
|
17
17
|
var parseUtils_1 = require("./parseUtils");
|
|
18
18
|
var sets_1 = require("../../utils/lang/sets");
|
|
19
|
-
var murmur3_1 = require("../../utils/murmur3/murmur3");
|
|
20
19
|
var murmur3_64_1 = require("../../utils/murmur3/murmur3_64");
|
|
21
20
|
var constants_3 = require("../../utils/constants");
|
|
22
|
-
function getDelay(parsedData, matchingKey) {
|
|
23
|
-
var interval = parsedData.i || 60000;
|
|
24
|
-
var seed = parsedData.s || 0;
|
|
25
|
-
return (0, murmur3_1.hash)(matchingKey, seed) % interval;
|
|
26
|
-
}
|
|
27
|
-
exports.getDelay = getDelay;
|
|
28
21
|
/**
|
|
29
22
|
* PushManager factory:
|
|
30
23
|
* - for server-side if key is not provided in settings.
|
|
@@ -55,10 +48,10 @@ function pushManagerFactory(params, pollingManager) {
|
|
|
55
48
|
var segmentsUpdateWorker = userKey ? undefined : (0, SegmentsUpdateWorker_1.SegmentsUpdateWorker)(log, pollingManager.segmentsSyncTask, storage.segments);
|
|
56
49
|
// For server-side we pass the segmentsSyncTask, used by SplitsUpdateWorker to fetch new segments
|
|
57
50
|
var splitsUpdateWorker = (0, SplitsUpdateWorker_1.SplitsUpdateWorker)(log, storage.splits, pollingManager.splitsSyncTask, readiness.splits, telemetryTracker, userKey ? undefined : pollingManager.segmentsSyncTask);
|
|
58
|
-
// [Only for client-side] map of hashes to user keys, to dispatch
|
|
51
|
+
// [Only for client-side] map of hashes to user keys, to dispatch membership update events to the corresponding MySegmentsUpdateWorker
|
|
59
52
|
var userKeyHashes = {};
|
|
60
53
|
// [Only for client-side] map of user keys to their corresponding hash64 and MySegmentsUpdateWorkers.
|
|
61
|
-
// Hash64 is used to process
|
|
54
|
+
// Hash64 is used to process membership update events and dispatch actions to the corresponding MySegmentsUpdateWorker.
|
|
62
55
|
var clients = {};
|
|
63
56
|
// [Only for client-side] variable to flag that a new client was added. It is needed to reconnect streaming.
|
|
64
57
|
var connectForNewClient = false;
|
|
@@ -152,7 +145,7 @@ function pushManagerFactory(params, pollingManager) {
|
|
|
152
145
|
(0, lang_1.forOwn)(clients, function (_a) {
|
|
153
146
|
var worker = _a.worker, workerLarge = _a.workerLarge;
|
|
154
147
|
worker.stop();
|
|
155
|
-
workerLarge
|
|
148
|
+
workerLarge.stop();
|
|
156
149
|
});
|
|
157
150
|
else
|
|
158
151
|
segmentsUpdateWorker.stop();
|
|
@@ -207,7 +200,7 @@ function pushManagerFactory(params, pollingManager) {
|
|
|
207
200
|
splitsUpdateWorker.put(parsedData);
|
|
208
201
|
});
|
|
209
202
|
function handleMySegmentsUpdate(parsedData) {
|
|
210
|
-
var isLS = parsedData.type === constants_1.
|
|
203
|
+
var isLS = parsedData.type === constants_1.MEMBERSHIP_LS_UPDATE;
|
|
211
204
|
switch (parsedData.u) {
|
|
212
205
|
case types_1.UpdateStrategy.BoundedFetchRequest: {
|
|
213
206
|
var bitmap_1;
|
|
@@ -215,15 +208,13 @@ function pushManagerFactory(params, pollingManager) {
|
|
|
215
208
|
bitmap_1 = (0, parseUtils_1.parseBitmap)(parsedData.d, parsedData.c);
|
|
216
209
|
}
|
|
217
210
|
catch (e) {
|
|
218
|
-
log.warn(constants_2.
|
|
211
|
+
log.warn(constants_2.STREAMING_PARSING_MEMBERSHIP_UPDATE, ['BoundedFetchRequest', e]);
|
|
219
212
|
break;
|
|
220
213
|
}
|
|
221
214
|
(0, lang_1.forOwn)(clients, function (_a, matchingKey) {
|
|
222
215
|
var hash64 = _a.hash64, worker = _a.worker, workerLarge = _a.workerLarge;
|
|
223
216
|
if ((0, parseUtils_1.isInBitmap)(bitmap_1, hash64.hex)) {
|
|
224
|
-
isLS ?
|
|
225
|
-
workerLarge && workerLarge.put(parsedData.changeNumber, undefined, getDelay(parsedData, matchingKey)) :
|
|
226
|
-
worker.put(parsedData.changeNumber);
|
|
217
|
+
(isLS ? workerLarge : worker).put(parsedData, undefined, (0, parseUtils_1.getDelay)(parsedData, matchingKey));
|
|
227
218
|
}
|
|
228
219
|
});
|
|
229
220
|
return;
|
|
@@ -236,65 +227,48 @@ function pushManagerFactory(params, pollingManager) {
|
|
|
236
227
|
removed_1 = new sets_1._Set(keyList.r);
|
|
237
228
|
}
|
|
238
229
|
catch (e) {
|
|
239
|
-
log.warn(constants_2.
|
|
230
|
+
log.warn(constants_2.STREAMING_PARSING_MEMBERSHIP_UPDATE, ['KeyList', e]);
|
|
231
|
+
break;
|
|
232
|
+
}
|
|
233
|
+
if (!parsedData.n || !parsedData.n.length) {
|
|
234
|
+
log.warn(constants_2.STREAMING_PARSING_MEMBERSHIP_UPDATE, ['KeyList', 'No segment name was provided']);
|
|
240
235
|
break;
|
|
241
236
|
}
|
|
242
237
|
(0, lang_1.forOwn)(clients, function (_a) {
|
|
243
238
|
var hash64 = _a.hash64, worker = _a.worker, workerLarge = _a.workerLarge;
|
|
244
239
|
var add = added_1.has(hash64.dec) ? true : removed_1.has(hash64.dec) ? false : undefined;
|
|
245
240
|
if (add !== undefined) {
|
|
246
|
-
isLS ?
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
}) :
|
|
251
|
-
worker.put(parsedData.changeNumber, {
|
|
252
|
-
name: parsedData.segmentName,
|
|
253
|
-
add: add
|
|
254
|
-
});
|
|
241
|
+
(isLS ? workerLarge : worker).put(parsedData, {
|
|
242
|
+
added: add ? [parsedData.n[0]] : [],
|
|
243
|
+
removed: add ? [] : [parsedData.n[0]]
|
|
244
|
+
});
|
|
255
245
|
}
|
|
256
246
|
});
|
|
257
247
|
return;
|
|
258
248
|
}
|
|
259
249
|
case types_1.UpdateStrategy.SegmentRemoval:
|
|
260
|
-
if (
|
|
261
|
-
log.warn(constants_2.
|
|
250
|
+
if (!parsedData.n || !parsedData.n.length) {
|
|
251
|
+
log.warn(constants_2.STREAMING_PARSING_MEMBERSHIP_UPDATE, ['SegmentRemoval', 'No segment name was provided']);
|
|
262
252
|
break;
|
|
263
253
|
}
|
|
264
254
|
(0, lang_1.forOwn)(clients, function (_a) {
|
|
265
255
|
var worker = _a.worker, workerLarge = _a.workerLarge;
|
|
266
|
-
isLS ?
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
add: false
|
|
271
|
-
});
|
|
272
|
-
}) :
|
|
273
|
-
worker.put(parsedData.changeNumber, {
|
|
274
|
-
name: parsedData.segmentName,
|
|
275
|
-
add: false
|
|
276
|
-
});
|
|
256
|
+
(isLS ? workerLarge : worker).put(parsedData, {
|
|
257
|
+
added: [],
|
|
258
|
+
removed: parsedData.n
|
|
259
|
+
});
|
|
277
260
|
});
|
|
278
261
|
return;
|
|
279
262
|
}
|
|
280
263
|
// `UpdateStrategy.UnboundedFetchRequest` and fallbacks of other cases
|
|
281
264
|
(0, lang_1.forOwn)(clients, function (_a, matchingKey) {
|
|
282
265
|
var worker = _a.worker, workerLarge = _a.workerLarge;
|
|
283
|
-
isLS ?
|
|
284
|
-
workerLarge && workerLarge.put(parsedData.changeNumber, undefined, getDelay(parsedData, matchingKey)) :
|
|
285
|
-
worker.put(parsedData.changeNumber);
|
|
266
|
+
(isLS ? workerLarge : worker).put(parsedData, undefined, (0, parseUtils_1.getDelay)(parsedData, matchingKey));
|
|
286
267
|
});
|
|
287
268
|
}
|
|
288
269
|
if (userKey) {
|
|
289
|
-
pushEmitter.on(constants_1.
|
|
290
|
-
|
|
291
|
-
var userKey = userKeyHashes[userKeyHash];
|
|
292
|
-
if (userKey && clients[userKey]) { // check existence since it can be undefined if client has been destroyed
|
|
293
|
-
clients[userKey].worker.put(parsedData.changeNumber, parsedData.includesPayload ? parsedData.segmentList ? parsedData.segmentList : [] : undefined);
|
|
294
|
-
}
|
|
295
|
-
});
|
|
296
|
-
pushEmitter.on(constants_1.MY_SEGMENTS_UPDATE_V2, handleMySegmentsUpdate);
|
|
297
|
-
pushEmitter.on(constants_1.MY_LARGE_SEGMENTS_UPDATE, handleMySegmentsUpdate);
|
|
270
|
+
pushEmitter.on(constants_1.MEMBERSHIP_MS_UPDATE, handleMySegmentsUpdate);
|
|
271
|
+
pushEmitter.on(constants_1.MEMBERSHIP_LS_UPDATE, handleMySegmentsUpdate);
|
|
298
272
|
}
|
|
299
273
|
else {
|
|
300
274
|
pushEmitter.on(constants_1.SEGMENT_UPDATE, segmentsUpdateWorker.put);
|
|
@@ -317,7 +291,7 @@ function pushManagerFactory(params, pollingManager) {
|
|
|
317
291
|
return;
|
|
318
292
|
disconnected = false;
|
|
319
293
|
if (userKey)
|
|
320
|
-
this.add(userKey, pollingManager.segmentsSyncTask
|
|
294
|
+
this.add(userKey, pollingManager.segmentsSyncTask); // client-side
|
|
321
295
|
else
|
|
322
296
|
setTimeout(connectPush); // server-side runs in next cycle as in client-side, for consistency with client-side
|
|
323
297
|
},
|
|
@@ -326,14 +300,14 @@ function pushManagerFactory(params, pollingManager) {
|
|
|
326
300
|
return disconnected === false;
|
|
327
301
|
},
|
|
328
302
|
// [Only for client-side]
|
|
329
|
-
add: function (userKey, mySegmentsSyncTask
|
|
303
|
+
add: function (userKey, mySegmentsSyncTask) {
|
|
330
304
|
var hash = (0, AuthClient_1.hashUserKey)(userKey);
|
|
331
305
|
if (!userKeyHashes[hash]) {
|
|
332
306
|
userKeyHashes[hash] = userKey;
|
|
333
307
|
clients[userKey] = {
|
|
334
308
|
hash64: (0, murmur3_64_1.hash64)(userKey),
|
|
335
|
-
worker: (0, MySegmentsUpdateWorker_1.MySegmentsUpdateWorker)(mySegmentsSyncTask, telemetryTracker
|
|
336
|
-
workerLarge:
|
|
309
|
+
worker: (0, MySegmentsUpdateWorker_1.MySegmentsUpdateWorker)(mySegmentsSyncTask, telemetryTracker),
|
|
310
|
+
workerLarge: (0, MySegmentsUpdateWorker_1.MySegmentsUpdateWorker)(mySegmentsSyncTask, telemetryTracker)
|
|
337
311
|
};
|
|
338
312
|
connectForNewClient = true; // we must reconnect on start, to listen the channel for the new user key
|
|
339
313
|
// Reconnects in case of a new client.
|
|
@@ -65,12 +65,10 @@ function telemetryCacheConfigAdapter(telemetry, settings) {
|
|
|
65
65
|
var _a = getTelemetryFlagSetsStats(settings.sync.__splitFiltersValidation), flagSetsTotal = _a.flagSetsTotal, flagSetsIgnored = _a.flagSetsIgnored;
|
|
66
66
|
return (0, objectAssign_1.objectAssign)(getTelemetryConfigStats(settings.mode, settings.storage.type), {
|
|
67
67
|
sE: settings.streamingEnabled,
|
|
68
|
-
lE: isClientSide ? settings.sync.largeSegmentsEnabled : undefined,
|
|
69
68
|
rR: {
|
|
70
69
|
sp: scheduler.featuresRefreshRate / 1000,
|
|
71
70
|
se: isClientSide ? undefined : scheduler.segmentsRefreshRate / 1000,
|
|
72
71
|
ms: isClientSide ? scheduler.segmentsRefreshRate / 1000 : undefined,
|
|
73
|
-
mls: isClientSide && settings.sync.largeSegmentsEnabled ? scheduler.largeSegmentsRefreshRate / 1000 : undefined,
|
|
74
72
|
im: scheduler.impressionsRefreshRate / 1000,
|
|
75
73
|
ev: scheduler.eventsPushRate / 1000,
|
|
76
74
|
te: scheduler.telemetryRefreshRate / 1000,
|
|
@@ -117,53 +117,43 @@ function syncManagerOnlineFactory(pollingManagerFactory, pushManagerFactory) {
|
|
|
117
117
|
shared: function (matchingKey, readinessManager, storage) {
|
|
118
118
|
if (!pollingManager)
|
|
119
119
|
return;
|
|
120
|
-
var
|
|
120
|
+
var mySegmentsSyncTask = pollingManager.add(matchingKey, readinessManager, storage);
|
|
121
121
|
return {
|
|
122
|
-
isRunning:
|
|
122
|
+
isRunning: mySegmentsSyncTask.isRunning,
|
|
123
123
|
start: function () {
|
|
124
124
|
if (syncEnabled) {
|
|
125
125
|
if (pushManager) {
|
|
126
126
|
if (pollingManager.isRunning()) {
|
|
127
127
|
// if doing polling, we must start the periodic fetch of data
|
|
128
|
-
if (storage.splits.
|
|
129
|
-
|
|
130
|
-
if (mlsSyncTask && storage.splits.usesMatcher(constants_3.IN_LARGE_SEGMENT))
|
|
131
|
-
mlsSyncTask.start();
|
|
128
|
+
if (storage.splits.usesSegments())
|
|
129
|
+
mySegmentsSyncTask.start();
|
|
132
130
|
}
|
|
133
131
|
else {
|
|
134
132
|
// if not polling, we must execute the sync task for the initial fetch
|
|
135
133
|
// of segments since `syncAll` was already executed when starting the main client
|
|
136
|
-
|
|
137
|
-
mlsSyncTask && mlsSyncTask.execute();
|
|
134
|
+
mySegmentsSyncTask.execute();
|
|
138
135
|
}
|
|
139
|
-
pushManager.add(matchingKey,
|
|
136
|
+
pushManager.add(matchingKey, mySegmentsSyncTask);
|
|
140
137
|
}
|
|
141
138
|
else {
|
|
142
|
-
if (storage.splits.
|
|
143
|
-
|
|
144
|
-
if (mlsSyncTask && storage.splits.usesMatcher(constants_3.IN_LARGE_SEGMENT))
|
|
145
|
-
mlsSyncTask.start();
|
|
139
|
+
if (storage.splits.usesSegments())
|
|
140
|
+
mySegmentsSyncTask.start();
|
|
146
141
|
}
|
|
147
142
|
}
|
|
148
143
|
else {
|
|
149
|
-
if (!readinessManager.isReady())
|
|
150
|
-
|
|
151
|
-
mlsSyncTask && mlsSyncTask.execute();
|
|
152
|
-
}
|
|
144
|
+
if (!readinessManager.isReady())
|
|
145
|
+
mySegmentsSyncTask.execute();
|
|
153
146
|
}
|
|
154
147
|
},
|
|
155
148
|
stop: function () {
|
|
156
149
|
// check in case `client.destroy()` has been invoked more than once for the same client
|
|
157
|
-
var
|
|
158
|
-
if (
|
|
159
|
-
var msSyncTask_1 = syncTasks.msSyncTask, mlsSyncTask_1 = syncTasks.mlsSyncTask;
|
|
150
|
+
var mySegmentsSyncTask = pollingManager.get(matchingKey);
|
|
151
|
+
if (mySegmentsSyncTask) {
|
|
160
152
|
// stop syncing
|
|
161
153
|
if (pushManager)
|
|
162
154
|
pushManager.remove(matchingKey);
|
|
163
|
-
if (
|
|
164
|
-
|
|
165
|
-
if (mlsSyncTask_1 && mlsSyncTask_1.isRunning())
|
|
166
|
-
mlsSyncTask_1.stop();
|
|
155
|
+
if (mySegmentsSyncTask.isRunning())
|
|
156
|
+
mySegmentsSyncTask.stop();
|
|
167
157
|
pollingManager.remove(matchingKey);
|
|
168
158
|
}
|
|
169
159
|
},
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
exports.IN_LARGE_SEGMENT = exports.IN_SEGMENT = exports.FLAG_SPEC_VERSION = exports.PAUSED = exports.ENABLED = exports.DISABLED = exports.NON_REQUESTED = exports.REQUESTED = exports.POLLING = exports.STREAMING = exports.AUTH_REJECTION = exports.SYNC_MODE_UPDATE = exports.ABLY_ERROR = exports.TOKEN_REFRESH = exports.SSE_CONNECTION_ERROR = exports.STREAMING_STATUS = exports.OCCUPANCY_SEC = exports.OCCUPANCY_PRI = exports.CONNECTION_ESTABLISHED = exports.TRACK = exports.TREATMENTS_WITH_CONFIG_BY_FLAGSETS = exports.TREATMENTS_WITH_CONFIG_BY_FLAGSET = exports.TREATMENTS_BY_FLAGSETS = exports.TREATMENTS_BY_FLAGSET = exports.TREATMENTS_WITH_CONFIG = exports.TREATMENT_WITH_CONFIG = exports.TREATMENTS = exports.TREATMENT =
|
|
3
|
+
exports.MEMBERSHIPS = exports.SEGMENT = exports.TOKEN = exports.TELEMETRY = exports.EVENTS = exports.IMPRESSIONS_COUNT = exports.IMPRESSIONS = exports.SPLITS = exports.NONE_ENUM = exports.DEBUG_ENUM = exports.OPTIMIZED_ENUM = exports.CONSUMER_PARTIAL_ENUM = exports.CONSUMER_ENUM = exports.STANDALONE_ENUM = exports.DEDUPED = exports.DROPPED = exports.QUEUED = exports.NAMES_FN_LABEL = exports.SPLITS_FN_LABEL = exports.SPLIT_FN_LABEL = exports.TRACK_FN_LABEL = exports.GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SETS = exports.GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SET = exports.GET_TREATMENTS_BY_FLAG_SETS = exports.GET_TREATMENTS_BY_FLAG_SET = exports.GET_TREATMENTS_WITH_CONFIG = exports.GET_TREATMENT_WITH_CONFIG = exports.GET_TREATMENTS = exports.GET_TREATMENT = exports.CONSENT_UNKNOWN = exports.CONSENT_DECLINED = exports.CONSENT_GRANTED = exports.STORAGE_PLUGGABLE = exports.STORAGE_REDIS = exports.STORAGE_LOCALSTORAGE = exports.STORAGE_MEMORY = exports.CONSUMER_PARTIAL_MODE = exports.CONSUMER_MODE = exports.PRODUCER_MODE = exports.STANDALONE_MODE = exports.LOCALHOST_MODE = exports.NONE = exports.OPTIMIZED = exports.DEBUG = exports.SPLIT_EVENT = exports.SPLIT_IMPRESSION = exports.NA = exports.UNKNOWN = exports.CONTROL_WITH_CONFIG = exports.CONTROL = void 0;
|
|
4
|
+
exports.IN_LARGE_SEGMENT = exports.IN_SEGMENT = exports.FLAG_SPEC_VERSION = exports.PAUSED = exports.ENABLED = exports.DISABLED = exports.NON_REQUESTED = exports.REQUESTED = exports.POLLING = exports.STREAMING = exports.AUTH_REJECTION = exports.SYNC_MODE_UPDATE = exports.ABLY_ERROR = exports.TOKEN_REFRESH = exports.SSE_CONNECTION_ERROR = exports.STREAMING_STATUS = exports.OCCUPANCY_SEC = exports.OCCUPANCY_PRI = exports.CONNECTION_ESTABLISHED = exports.TRACK = exports.TREATMENTS_WITH_CONFIG_BY_FLAGSETS = exports.TREATMENTS_WITH_CONFIG_BY_FLAGSET = exports.TREATMENTS_BY_FLAGSETS = exports.TREATMENTS_BY_FLAGSET = exports.TREATMENTS_WITH_CONFIG = exports.TREATMENT_WITH_CONFIG = exports.TREATMENTS = exports.TREATMENT = void 0;
|
|
5
5
|
// Special treatments
|
|
6
6
|
exports.CONTROL = 'control';
|
|
7
7
|
exports.CONTROL_WITH_CONFIG = {
|
|
@@ -64,8 +64,7 @@ exports.EVENTS = 'ev';
|
|
|
64
64
|
exports.TELEMETRY = 'te';
|
|
65
65
|
exports.TOKEN = 'to';
|
|
66
66
|
exports.SEGMENT = 'se';
|
|
67
|
-
exports.
|
|
68
|
-
exports.MY_LARGE_SEGMENT = 'mls';
|
|
67
|
+
exports.MEMBERSHIPS = 'ms';
|
|
69
68
|
exports.TREATMENT = 't';
|
|
70
69
|
exports.TREATMENTS = 'ts';
|
|
71
70
|
exports.TREATMENT_WITH_CONFIG = 'tc';
|
|
@@ -91,7 +90,7 @@ exports.NON_REQUESTED = 1;
|
|
|
91
90
|
exports.DISABLED = 0;
|
|
92
91
|
exports.ENABLED = 1;
|
|
93
92
|
exports.PAUSED = 2;
|
|
94
|
-
exports.FLAG_SPEC_VERSION = '1.
|
|
93
|
+
exports.FLAG_SPEC_VERSION = '1.2';
|
|
95
94
|
// Matcher types
|
|
96
95
|
exports.IN_SEGMENT = 'IN_SEGMENT';
|
|
97
96
|
exports.IN_LARGE_SEGMENT = 'IN_LARGE_SEGMENT';
|
|
@@ -30,8 +30,6 @@ exports.base = {
|
|
|
30
30
|
featuresRefreshRate: 60,
|
|
31
31
|
// fetch segments updates each 60 sec
|
|
32
32
|
segmentsRefreshRate: 60,
|
|
33
|
-
// fetch large segments updates each 60 sec
|
|
34
|
-
largeSegmentsRefreshRate: 60,
|
|
35
33
|
// publish telemetry stats each 3600 secs (1 hour)
|
|
36
34
|
telemetryRefreshRate: 3600,
|
|
37
35
|
// publish evaluations each 300 sec (default value for OPTIMIZED impressions mode)
|
|
@@ -77,8 +75,7 @@ exports.base = {
|
|
|
77
75
|
impressionsMode: constants_1.OPTIMIZED,
|
|
78
76
|
localhostMode: undefined,
|
|
79
77
|
enabled: true,
|
|
80
|
-
flagSpecVersion: constants_1.FLAG_SPEC_VERSION
|
|
81
|
-
largeSegmentsEnabled: false
|
|
78
|
+
flagSpecVersion: constants_1.FLAG_SPEC_VERSION
|
|
82
79
|
},
|
|
83
80
|
// Logger
|
|
84
81
|
log: undefined
|
|
@@ -117,7 +114,6 @@ function settingsValidation(config, validationParams) {
|
|
|
117
114
|
var scheduler = withDefaults.scheduler, startup = withDefaults.startup;
|
|
118
115
|
scheduler.featuresRefreshRate = fromSecondsToMillis(scheduler.featuresRefreshRate);
|
|
119
116
|
scheduler.segmentsRefreshRate = fromSecondsToMillis(scheduler.segmentsRefreshRate);
|
|
120
|
-
scheduler.largeSegmentsRefreshRate = fromSecondsToMillis(scheduler.largeSegmentsRefreshRate);
|
|
121
117
|
scheduler.offlineRefreshRate = fromSecondsToMillis(scheduler.offlineRefreshRate);
|
|
122
118
|
scheduler.eventsPushRate = fromSecondsToMillis(scheduler.eventsPushRate);
|
|
123
119
|
scheduler.telemetryRefreshRate = fromSecondsToMillis(validateMinValue('telemetryRefreshRate', scheduler.telemetryRefreshRate, 60));
|
package/esm/logger/constants.js
CHANGED
|
@@ -35,6 +35,7 @@ export var IMPRESSION = 102;
|
|
|
35
35
|
export var IMPRESSION_QUEUEING = 103;
|
|
36
36
|
export var NEW_SHARED_CLIENT = 104;
|
|
37
37
|
export var NEW_FACTORY = 105;
|
|
38
|
+
export var POLLING_SMART_PAUSING = 106;
|
|
38
39
|
export var POLLING_START = 107;
|
|
39
40
|
export var POLLING_STOP = 108;
|
|
40
41
|
export var SYNC_SPLITS_FETCH_RETRY = 109;
|
|
@@ -76,7 +77,7 @@ export var WARN_SPLITS_FILTER_IGNORED = 219;
|
|
|
76
77
|
export var WARN_SPLITS_FILTER_INVALID = 220;
|
|
77
78
|
export var WARN_SPLITS_FILTER_EMPTY = 221;
|
|
78
79
|
export var WARN_SDK_KEY = 222;
|
|
79
|
-
export var
|
|
80
|
+
export var STREAMING_PARSING_MEMBERSHIP_UPDATE = 223;
|
|
80
81
|
export var STREAMING_PARSING_SPLIT_UPDATE = 224;
|
|
81
82
|
export var WARN_INVALID_FLAGSET = 225;
|
|
82
83
|
export var WARN_LOWERCASE_FLAGSET = 226;
|
|
@@ -16,10 +16,11 @@ export var codesInfo = codesWarn.concat([
|
|
|
16
16
|
[c.USER_CONSENT_NOT_UPDATED, 'UserConsent: call had no effect because it was the current consent status (%s).'],
|
|
17
17
|
[c.USER_CONSENT_INITIAL, 'Starting the SDK with %s user consent. No data will be sent.'],
|
|
18
18
|
// synchronizer
|
|
19
|
+
[c.POLLING_SMART_PAUSING, c.LOG_PREFIX_SYNC_POLLING + 'Turning segments data polling %s.'],
|
|
19
20
|
[c.POLLING_START, c.LOG_PREFIX_SYNC_POLLING + 'Starting polling'],
|
|
20
21
|
[c.POLLING_STOP, c.LOG_PREFIX_SYNC_POLLING + 'Stopping polling'],
|
|
21
22
|
[c.SYNC_SPLITS_FETCH_RETRY, c.LOG_PREFIX_SYNC_SPLITS + 'Retrying download of feature flags #%s. Reason: %s'],
|
|
22
|
-
[c.SUBMITTERS_PUSH_FULL_QUEUE, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Flushing full %s queue and
|
|
23
|
+
[c.SUBMITTERS_PUSH_FULL_QUEUE, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Flushing full %s queue and resetting timer.'],
|
|
23
24
|
[c.SUBMITTERS_PUSH, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Pushing %s.'],
|
|
24
25
|
[c.STREAMING_REFRESH_TOKEN, c.LOG_PREFIX_SYNC_STREAMING + 'Refreshing streaming token in %s seconds, and connecting streaming in %s seconds.'],
|
|
25
26
|
[c.STREAMING_RECONNECT, c.LOG_PREFIX_SYNC_STREAMING + 'Attempting to reconnect streaming in %s seconds.'],
|
|
@@ -30,7 +30,7 @@ export var codesWarn = codesError.concat([
|
|
|
30
30
|
[c.WARN_SPLITS_FILTER_INVALID, c.LOG_PREFIX_SETTINGS + ': feature flag filter at position %s is invalid. It must be an object with a valid filter type ("bySet", "byName" or "byPrefix") and a list of "values".'],
|
|
31
31
|
[c.WARN_SPLITS_FILTER_EMPTY, c.LOG_PREFIX_SETTINGS + ': feature flag filter configuration must be a non-empty array of filter objects.'],
|
|
32
32
|
[c.WARN_SDK_KEY, c.LOG_PREFIX_SETTINGS + ': You already have %s. We recommend keeping only one instance of the factory at all times (Singleton pattern) and reusing it throughout your application'],
|
|
33
|
-
[c.
|
|
33
|
+
[c.STREAMING_PARSING_MEMBERSHIP_UPDATE, c.LOG_PREFIX_SYNC_STREAMING + 'Fetching Memberships due to an error processing %s notification: %s'],
|
|
34
34
|
[c.STREAMING_PARSING_SPLIT_UPDATE, c.LOG_PREFIX_SYNC_STREAMING + 'Fetching SplitChanges due to an error processing SPLIT_UPDATE notification: %s'],
|
|
35
35
|
[c.WARN_INVALID_FLAGSET, '%s: you passed %s, flag set must adhere to the regular expressions %s. This means a flag set must start with a letter or number, be in lowercase, alphanumeric and have a max length of 50 characters. %s was discarded.'],
|
|
36
36
|
[c.WARN_LOWERCASE_FLAGSET, '%s: flag set %s should be all lowercase - converting string to lowercase.'],
|
|
@@ -6,16 +6,17 @@ function splitsEventEmitterFactory(EventEmitter) {
|
|
|
6
6
|
splitsCacheLoaded: false,
|
|
7
7
|
});
|
|
8
8
|
// `isSplitKill` condition avoids an edge-case of wrongly emitting SDK_READY if:
|
|
9
|
-
// - `/
|
|
9
|
+
// - `/memberships` fetch and SPLIT_KILL occurs before `/splitChanges` fetch, and
|
|
10
10
|
// - storage has cached splits (for which case `splitsStorage.killLocally` can return true)
|
|
11
11
|
splitsEventEmitter.on(SDK_SPLITS_ARRIVED, function (isSplitKill) { if (!isSplitKill)
|
|
12
12
|
splitsEventEmitter.splitsArrived = true; });
|
|
13
13
|
splitsEventEmitter.once(SDK_SPLITS_CACHE_LOADED, function () { splitsEventEmitter.splitsCacheLoaded = true; });
|
|
14
14
|
return splitsEventEmitter;
|
|
15
15
|
}
|
|
16
|
-
function segmentsEventEmitterFactory(EventEmitter
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
function segmentsEventEmitterFactory(EventEmitter) {
|
|
17
|
+
var segmentsEventEmitter = objectAssign(new EventEmitter(), {
|
|
18
|
+
segmentsArrived: false
|
|
19
|
+
});
|
|
19
20
|
segmentsEventEmitter.once(SDK_SEGMENTS_ARRIVED, function () { segmentsEventEmitter.segmentsArrived = true; });
|
|
20
21
|
return segmentsEventEmitter;
|
|
21
22
|
}
|
|
@@ -24,9 +25,8 @@ function segmentsEventEmitterFactory(EventEmitter, segmentsArrived) {
|
|
|
24
25
|
*/
|
|
25
26
|
export function readinessManagerFactory(EventEmitter, settings, splits) {
|
|
26
27
|
if (splits === void 0) { splits = splitsEventEmitterFactory(EventEmitter); }
|
|
27
|
-
var
|
|
28
|
+
var readyTimeout = settings.startup.readyTimeout;
|
|
28
29
|
var segments = segmentsEventEmitterFactory(EventEmitter);
|
|
29
|
-
var largeSegments = largeSegmentsEnabled ? segmentsEventEmitterFactory(EventEmitter, !waitForLargeSegments) : undefined;
|
|
30
30
|
var gate = new EventEmitter();
|
|
31
31
|
// emit SDK_READY_FROM_CACHE
|
|
32
32
|
var isReadyFromCache = false;
|
|
@@ -50,8 +50,6 @@ export function readinessManagerFactory(EventEmitter, settings, splits) {
|
|
|
50
50
|
var isReady = false;
|
|
51
51
|
splits.on(SDK_SPLITS_ARRIVED, checkIsReadyOrUpdate);
|
|
52
52
|
segments.on(SDK_SEGMENTS_ARRIVED, checkIsReadyOrUpdate);
|
|
53
|
-
if (largeSegments)
|
|
54
|
-
largeSegments.on(SDK_SEGMENTS_ARRIVED, checkIsReadyOrUpdate);
|
|
55
53
|
var isDestroyed = false;
|
|
56
54
|
function checkIsReadyFromCache() {
|
|
57
55
|
isReadyFromCache = true;
|
|
@@ -77,7 +75,7 @@ export function readinessManagerFactory(EventEmitter, settings, splits) {
|
|
|
77
75
|
}
|
|
78
76
|
}
|
|
79
77
|
else {
|
|
80
|
-
if (splits.splitsArrived && segments.segmentsArrived
|
|
78
|
+
if (splits.splitsArrived && segments.segmentsArrived) {
|
|
81
79
|
clearTimeout(readyTimeoutId);
|
|
82
80
|
isReady = true;
|
|
83
81
|
try {
|
|
@@ -94,7 +92,6 @@ export function readinessManagerFactory(EventEmitter, settings, splits) {
|
|
|
94
92
|
return {
|
|
95
93
|
splits: splits,
|
|
96
94
|
segments: segments,
|
|
97
|
-
largeSegments: largeSegments,
|
|
98
95
|
gate: gate,
|
|
99
96
|
shared: function () {
|
|
100
97
|
refCount++;
|
|
@@ -109,8 +106,6 @@ export function readinessManagerFactory(EventEmitter, settings, splits) {
|
|
|
109
106
|
destroy: function () {
|
|
110
107
|
isDestroyed = true;
|
|
111
108
|
segments.removeAllListeners();
|
|
112
|
-
if (largeSegments)
|
|
113
|
-
largeSegments.removeAllListeners();
|
|
114
109
|
gate.removeAllListeners();
|
|
115
110
|
clearTimeout(readyTimeoutId);
|
|
116
111
|
if (refCount > 0)
|
package/esm/services/splitApi.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { splitHttpClientFactory } from './splitHttpClient';
|
|
2
2
|
import { objectAssign } from '../utils/lang/objectAssign';
|
|
3
|
-
import { SPLITS, IMPRESSIONS, IMPRESSIONS_COUNT, EVENTS, TELEMETRY, TOKEN, SEGMENT,
|
|
3
|
+
import { SPLITS, IMPRESSIONS, IMPRESSIONS_COUNT, EVENTS, TELEMETRY, TOKEN, SEGMENT, MEMBERSHIPS } from '../utils/constants';
|
|
4
4
|
import { ERROR_TOO_MANY_SETS } from '../logger/constants';
|
|
5
5
|
var noCacheHeaderOptions = { headers: { 'Cache-Control': 'no-cache' } };
|
|
6
6
|
function userKeyToQueryParam(userKey) {
|
|
@@ -51,19 +51,15 @@ export function splitApiFactory(settings, platform, telemetryTracker) {
|
|
|
51
51
|
var url = urls.sdk + "/segmentChanges/" + segmentName + "?since=" + since + (till ? '&till=' + till : '');
|
|
52
52
|
return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined, telemetryTracker.trackHttp(SEGMENT));
|
|
53
53
|
},
|
|
54
|
-
|
|
54
|
+
fetchMemberships: function (userMatchingKey, noCache) {
|
|
55
55
|
/**
|
|
56
56
|
* URI encoding of user keys in order to:
|
|
57
|
-
* - avoid 400 responses (due to URI malformed). E.g.: '/api/
|
|
58
|
-
* - avoid 404 responses. E.g.: '/api/
|
|
57
|
+
* - avoid 400 responses (due to URI malformed). E.g.: '/api/memberships/%'
|
|
58
|
+
* - avoid 404 responses. E.g.: '/api/memberships/foo/bar'
|
|
59
59
|
* - match user keys with special characters. E.g.: 'foo%bar', 'foo/bar'
|
|
60
60
|
*/
|
|
61
|
-
var url = urls.sdk + "/
|
|
62
|
-
return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined, telemetryTracker.trackHttp(
|
|
63
|
-
},
|
|
64
|
-
fetchMyLargeSegments: function (userMatchingKey, noCache) {
|
|
65
|
-
var url = urls.sdk + "/myLargeSegments/" + encodeURIComponent(userMatchingKey);
|
|
66
|
-
return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined, telemetryTracker.trackHttp(MY_LARGE_SEGMENT));
|
|
61
|
+
var url = urls.sdk + "/memberships/" + encodeURIComponent(userMatchingKey);
|
|
62
|
+
return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined, telemetryTracker.trackHttp(MEMBERSHIPS));
|
|
67
63
|
},
|
|
68
64
|
/**
|
|
69
65
|
* Post events.
|
|
@@ -6,25 +6,54 @@ var AbstractSegmentsCacheSync = /** @class */ (function () {
|
|
|
6
6
|
function AbstractSegmentsCacheSync() {
|
|
7
7
|
}
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
10
|
-
* For client-side synchronizer: the method is not used.
|
|
11
|
-
*/
|
|
12
|
-
AbstractSegmentsCacheSync.prototype.registerSegments = function (names) { return false; };
|
|
13
|
-
/**
|
|
14
|
-
* For server-side synchronizer: set the change number of `name` segment.
|
|
15
|
-
* For client-side synchronizer: the method is not used.
|
|
9
|
+
* clear the cache.
|
|
16
10
|
*/
|
|
17
|
-
AbstractSegmentsCacheSync.prototype.
|
|
11
|
+
AbstractSegmentsCacheSync.prototype.clear = function () {
|
|
12
|
+
this.resetSegments({});
|
|
13
|
+
};
|
|
18
14
|
/**
|
|
19
|
-
* For server-side synchronizer:
|
|
15
|
+
* For server-side synchronizer: add the given list of segments to the cache, with an empty list of keys. The segments that already exist are not modified.
|
|
20
16
|
* For client-side synchronizer: the method is not used.
|
|
21
17
|
*/
|
|
22
|
-
AbstractSegmentsCacheSync.prototype.
|
|
18
|
+
AbstractSegmentsCacheSync.prototype.registerSegments = function (names) { return false; };
|
|
23
19
|
/**
|
|
24
20
|
* For server-side synchronizer: the method is not used.
|
|
25
|
-
* For client-side synchronizer:
|
|
21
|
+
* For client-side synchronizer: it resets or updates the cache.
|
|
26
22
|
*/
|
|
27
|
-
AbstractSegmentsCacheSync.prototype.resetSegments = function (
|
|
23
|
+
AbstractSegmentsCacheSync.prototype.resetSegments = function (segmentsData) {
|
|
24
|
+
var _this = this;
|
|
25
|
+
this.setChangeNumber(undefined, segmentsData.cn);
|
|
26
|
+
var _a = segmentsData, added = _a.added, removed = _a.removed;
|
|
27
|
+
if (added && removed) {
|
|
28
|
+
var isDiff_1 = false;
|
|
29
|
+
added.forEach(function (segment) {
|
|
30
|
+
isDiff_1 = _this.addToSegment(segment) || isDiff_1;
|
|
31
|
+
});
|
|
32
|
+
removed.forEach(function (segment) {
|
|
33
|
+
isDiff_1 = _this.removeFromSegment(segment) || isDiff_1;
|
|
34
|
+
});
|
|
35
|
+
return isDiff_1;
|
|
36
|
+
}
|
|
37
|
+
var names = (segmentsData.k || []).map(function (s) { return s.n; }).sort();
|
|
38
|
+
var storedSegmentKeys = this.getRegisteredSegments().sort();
|
|
39
|
+
// Extreme fast => everything is empty
|
|
40
|
+
if (!names.length && !storedSegmentKeys.length)
|
|
41
|
+
return false;
|
|
42
|
+
var index = 0;
|
|
43
|
+
while (index < names.length && index < storedSegmentKeys.length && names[index] === storedSegmentKeys[index])
|
|
44
|
+
index++;
|
|
45
|
+
// Quick path => no changes
|
|
46
|
+
if (index === names.length && index === storedSegmentKeys.length)
|
|
47
|
+
return false;
|
|
48
|
+
// Slowest path => add and/or remove segments
|
|
49
|
+
for (var removeIndex = index; removeIndex < storedSegmentKeys.length; removeIndex++) {
|
|
50
|
+
this.removeFromSegment(storedSegmentKeys[removeIndex]);
|
|
51
|
+
}
|
|
52
|
+
for (var addIndex = index; addIndex < names.length; addIndex++) {
|
|
53
|
+
this.addToSegment(names[addIndex]);
|
|
54
|
+
}
|
|
55
|
+
return true;
|
|
56
|
+
};
|
|
28
57
|
return AbstractSegmentsCacheSync;
|
|
29
58
|
}());
|
|
30
59
|
export { AbstractSegmentsCacheSync };
|
|
@@ -6,9 +6,9 @@ import { objectAssign } from '../utils/lang/objectAssign';
|
|
|
6
6
|
var AbstractSplitsCacheAsync = /** @class */ (function () {
|
|
7
7
|
function AbstractSplitsCacheAsync() {
|
|
8
8
|
}
|
|
9
|
-
// @TODO revisit segment-related methods ('
|
|
9
|
+
// @TODO revisit segment-related methods ('usesSegments', 'getRegisteredSegments', 'registerSegments')
|
|
10
10
|
// noop, just keeping the interface. This is used by standalone client-side API only, and so only implemented by InMemory and InLocalStorage.
|
|
11
|
-
AbstractSplitsCacheAsync.prototype.
|
|
11
|
+
AbstractSplitsCacheAsync.prototype.usesSegments = function () {
|
|
12
12
|
return Promise.resolve(true);
|
|
13
13
|
};
|
|
14
14
|
/**
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { objectAssign } from '../utils/lang/objectAssign';
|
|
2
|
+
import { IN_SEGMENT, IN_LARGE_SEGMENT } from '../utils/constants';
|
|
2
3
|
/**
|
|
3
4
|
* This class provides a skeletal implementation of the ISplitsCacheSync interface
|
|
4
5
|
* to minimize the effort required to implement this interface.
|
|
@@ -59,14 +60,15 @@ var AbstractSplitsCacheSync = /** @class */ (function () {
|
|
|
59
60
|
export { AbstractSplitsCacheSync };
|
|
60
61
|
/**
|
|
61
62
|
* Given a parsed split, it returns a boolean flagging if its conditions use segments matchers (rules & whitelists).
|
|
62
|
-
* This util is intended to simplify the implementation of `splitsCache::
|
|
63
|
+
* This util is intended to simplify the implementation of `splitsCache::usesSegments` method
|
|
63
64
|
*/
|
|
64
|
-
export function
|
|
65
|
+
export function usesSegments(split) {
|
|
65
66
|
var conditions = split.conditions || [];
|
|
66
67
|
for (var i = 0; i < conditions.length; i++) {
|
|
67
68
|
var matchers = conditions[i].matcherGroup.matchers;
|
|
68
69
|
for (var j = 0; j < matchers.length; j++) {
|
|
69
|
-
|
|
70
|
+
var matcher = matchers[j].matcherType;
|
|
71
|
+
if (matcher === IN_SEGMENT || matcher === IN_LARGE_SEGMENT)
|
|
70
72
|
return true;
|
|
71
73
|
}
|
|
72
74
|
}
|
|
@@ -36,9 +36,6 @@ var KeyBuilder = /** @class */ (function () {
|
|
|
36
36
|
KeyBuilder.prototype.buildSplitsWithSegmentCountKey = function () {
|
|
37
37
|
return this.prefix + ".splits.usingSegments";
|
|
38
38
|
};
|
|
39
|
-
KeyBuilder.prototype.buildSplitsWithLargeSegmentCountKey = function () {
|
|
40
|
-
return this.prefix + ".splits.usingLargeSegments";
|
|
41
|
-
};
|
|
42
39
|
KeyBuilder.prototype.buildSegmentNameKey = function (segmentName) {
|
|
43
40
|
return this.prefix + ".segment." + segmentName;
|
|
44
41
|
};
|
|
@@ -32,6 +32,9 @@ var KeyBuilderCS = /** @class */ (function (_super) {
|
|
|
32
32
|
KeyBuilderCS.prototype.isSplitsCacheKey = function (key) {
|
|
33
33
|
return this.regexSplitsCacheKey.test(key);
|
|
34
34
|
};
|
|
35
|
+
KeyBuilderCS.prototype.buildTillKey = function () {
|
|
36
|
+
return this.prefix + "." + this.matchingKey + ".segments.till";
|
|
37
|
+
};
|
|
35
38
|
return KeyBuilderCS;
|
|
36
39
|
}(KeyBuilder));
|
|
37
40
|
export { KeyBuilderCS };
|
|
@@ -47,6 +50,9 @@ export function myLargeSegmentsKeyBuilder(prefix, matchingKey) {
|
|
|
47
50
|
},
|
|
48
51
|
extractOldSegmentKey: function () {
|
|
49
52
|
return undefined;
|
|
53
|
+
},
|
|
54
|
+
buildTillKey: function () {
|
|
55
|
+
return prefix + "." + matchingKey + ".largeSegments.till";
|
|
50
56
|
}
|
|
51
57
|
};
|
|
52
58
|
}
|
|
@@ -42,6 +42,6 @@ export function dataLoaderFactory(preloadedData) {
|
|
|
42
42
|
return Array.isArray(userIds) && userIds.indexOf(userId) > -1;
|
|
43
43
|
});
|
|
44
44
|
}
|
|
45
|
-
storage.segments.resetSegments(mySegmentsData);
|
|
45
|
+
storage.segments.resetSegments({ k: mySegmentsData.map(function (s) { return ({ n: s }); }) });
|
|
46
46
|
};
|
|
47
47
|
}
|