@splitsoftware/splitio-commons 3.1.1-rc.0 → 3.1.1-rc.10
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 +10 -1
- package/cjs/evaluator/condition/index.js +1 -1
- package/cjs/evaluator/fallbackTreatmentsCalculator/fallbackSanitizer/index.js +8 -5
- package/cjs/evaluator/index.js +69 -81
- package/cjs/listeners/browser.js +1 -2
- package/cjs/listeners/node.js +4 -4
- package/cjs/logger/constants.js +20 -15
- package/cjs/logger/messages/debug.js +6 -5
- package/cjs/logger/messages/error.js +3 -3
- package/cjs/logger/messages/info.js +4 -3
- package/cjs/logger/messages/warn.js +7 -6
- package/cjs/presets/serverSide.js +2 -2
- package/cjs/readiness/constants.js +4 -5
- package/cjs/readiness/readinessManager.js +23 -23
- package/cjs/readiness/sdkReadinessManager.js +17 -1
- package/cjs/sdkClient/client.js +34 -9
- package/cjs/sdkClient/clientInputValidation.js +17 -6
- package/cjs/sdkClient/sdkClient.js +60 -3
- package/cjs/sdkFactory/index.js +15 -11
- package/cjs/sdkManager/index.js +5 -5
- package/cjs/services/decorateHeaders.js +1 -2
- package/cjs/services/splitApi.js +1 -14
- package/cjs/services/splitHttpClient.js +5 -3
- package/cjs/storages/AbstractSplitsCacheAsync.js +51 -0
- package/cjs/storages/AbstractSplitsCacheSync.js +76 -0
- package/cjs/storages/KeyBuilder.js +6 -6
- package/cjs/storages/KeyBuilderCS.js +5 -5
- package/cjs/storages/KeyBuilderSS.js +2 -2
- package/cjs/storages/getRolloutPlan.js +3 -3
- package/cjs/storages/inLocalStorage/MySegmentsCacheInLocal.js +2 -1
- package/cjs/storages/inLocalStorage/RBSegmentsCacheInLocal.js +10 -10
- package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +194 -0
- package/cjs/storages/inLocalStorage/index.js +6 -6
- package/cjs/storages/inLocalStorage/validateCache.js +3 -3
- package/cjs/storages/inMemory/InMemoryStorage.js +4 -4
- package/cjs/storages/inMemory/InMemoryStorageCS.js +5 -5
- package/cjs/storages/inMemory/RBSegmentsCacheInMemory.js +5 -5
- package/cjs/storages/inMemory/SegmentsCacheInMemory.js +1 -1
- package/cjs/storages/inMemory/SplitsCacheInMemory.js +121 -0
- package/cjs/storages/inMemory/TelemetryCacheInMemory.js +5 -5
- package/cjs/storages/inRedis/RBSegmentsCacheInRedis.js +1 -1
- package/cjs/storages/inRedis/RedisAdapter.js +8 -5
- package/cjs/storages/inRedis/{DefinitionsCacheInRedis.js → SplitsCacheInRedis.js} +77 -77
- package/cjs/storages/inRedis/index.js +2 -2
- package/cjs/storages/pluggable/RBSegmentsCachePluggable.js +1 -1
- package/cjs/storages/pluggable/SplitsCachePluggable.js +212 -0
- package/cjs/storages/pluggable/index.js +2 -2
- package/cjs/storages/setRolloutPlan.js +4 -4
- package/cjs/storages/utils.js +0 -1
- package/cjs/sync/offline/syncTasks/fromObjectSyncTask.js +5 -5
- package/cjs/sync/polling/fetchers/splitChangesFetcher.js +15 -24
- package/cjs/sync/polling/pollingManagerCS.js +20 -20
- package/cjs/sync/polling/pollingManagerSS.js +15 -15
- package/cjs/sync/polling/syncTasks/segmentsSyncTask.js +3 -2
- package/cjs/sync/polling/syncTasks/splitsSyncTask.js +13 -0
- package/cjs/sync/polling/updaters/mySegmentsUpdater.js +3 -3
- package/cjs/sync/polling/updaters/segmentChangesUpdater.js +6 -6
- package/cjs/sync/polling/updaters/{definitionChangesUpdater.js → splitChangesUpdater.js} +68 -65
- package/cjs/sync/streaming/AuthClient/index.js +1 -1
- package/cjs/sync/streaming/SSEHandler/NotificationKeeper.js +1 -1
- package/cjs/sync/streaming/SSEHandler/index.js +1 -1
- package/cjs/sync/streaming/UpdateWorkers/{DefinitionsUpdateWorker.js → SplitsUpdateWorker.js} +19 -16
- package/cjs/sync/streaming/constants.js +3 -3
- package/cjs/sync/streaming/parseUtils.js +11 -11
- package/cjs/sync/streaming/pushManager.js +16 -16
- package/cjs/sync/submitters/eventsSubmitter.js +1 -1
- package/cjs/sync/submitters/impressionCountsSubmitter.js +1 -1
- package/cjs/sync/submitters/impressionsSubmitter.js +4 -5
- package/cjs/sync/submitters/telemetrySubmitter.js +4 -3
- package/cjs/sync/submitters/uniqueKeysSubmitter.js +1 -1
- package/cjs/sync/syncManagerOnline.js +7 -12
- package/cjs/utils/Backoff.js +0 -20
- package/cjs/utils/inputValidation/index.js +7 -7
- package/cjs/utils/inputValidation/isOperational.js +4 -4
- package/cjs/utils/inputValidation/{definition.js → split.js} +10 -10
- package/cjs/utils/inputValidation/{definitionExistence.js → splitExistence.js} +6 -6
- package/cjs/utils/inputValidation/splits.js +25 -0
- package/cjs/utils/labels/index.js +3 -3
- package/cjs/utils/settingsValidation/index.js +0 -2
- package/cjs/utils/settingsValidation/splitFilters.js +3 -3
- package/cjs/utils/settingsValidation/url.js +2 -6
- package/esm/evaluator/condition/index.js +1 -1
- package/esm/evaluator/fallbackTreatmentsCalculator/fallbackSanitizer/index.js +8 -5
- package/esm/evaluator/index.js +69 -80
- package/esm/listeners/browser.js +1 -2
- package/esm/listeners/node.js +4 -4
- package/esm/logger/constants.js +17 -12
- package/esm/logger/messages/debug.js +6 -5
- package/esm/logger/messages/error.js +3 -3
- package/esm/logger/messages/info.js +4 -3
- package/esm/logger/messages/warn.js +7 -6
- package/esm/presets/serverSide.js +2 -2
- package/esm/readiness/constants.js +3 -4
- package/esm/readiness/readinessManager.js +24 -24
- package/esm/readiness/sdkReadinessManager.js +18 -2
- package/esm/sdkClient/client.js +35 -9
- package/esm/sdkClient/clientInputValidation.js +19 -8
- package/esm/sdkClient/sdkClient.js +60 -3
- package/esm/sdkFactory/index.js +16 -12
- package/esm/sdkManager/index.js +6 -6
- package/esm/services/decorateHeaders.js +1 -2
- package/esm/services/splitApi.js +1 -14
- package/esm/services/splitHttpClient.js +5 -3
- package/esm/storages/AbstractSplitsCacheAsync.js +48 -0
- package/esm/storages/AbstractSplitsCacheSync.js +71 -0
- package/esm/storages/KeyBuilder.js +6 -6
- package/esm/storages/KeyBuilderCS.js +5 -5
- package/esm/storages/KeyBuilderSS.js +2 -2
- package/esm/storages/getRolloutPlan.js +3 -3
- package/esm/storages/inLocalStorage/MySegmentsCacheInLocal.js +2 -1
- package/esm/storages/inLocalStorage/RBSegmentsCacheInLocal.js +7 -7
- package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +191 -0
- package/esm/storages/inLocalStorage/index.js +6 -6
- package/esm/storages/inLocalStorage/validateCache.js +3 -3
- package/esm/storages/inMemory/InMemoryStorage.js +4 -4
- package/esm/storages/inMemory/InMemoryStorageCS.js +5 -5
- package/esm/storages/inMemory/RBSegmentsCacheInMemory.js +2 -2
- package/esm/storages/inMemory/SegmentsCacheInMemory.js +1 -1
- package/esm/storages/inMemory/SplitsCacheInMemory.js +118 -0
- package/esm/storages/inMemory/TelemetryCacheInMemory.js +5 -5
- package/esm/storages/inRedis/RBSegmentsCacheInRedis.js +1 -1
- package/esm/storages/inRedis/RedisAdapter.js +8 -5
- package/esm/storages/inRedis/{DefinitionsCacheInRedis.js → SplitsCacheInRedis.js} +76 -76
- package/esm/storages/inRedis/index.js +2 -2
- package/esm/storages/pluggable/RBSegmentsCachePluggable.js +1 -1
- package/esm/storages/pluggable/SplitsCachePluggable.js +209 -0
- package/esm/storages/pluggable/index.js +2 -2
- package/esm/storages/setRolloutPlan.js +4 -4
- package/esm/storages/utils.js +0 -1
- package/esm/sync/offline/syncTasks/fromObjectSyncTask.js +6 -6
- package/esm/sync/polling/fetchers/splitChangesFetcher.js +16 -25
- package/esm/sync/polling/pollingManagerCS.js +17 -17
- package/esm/sync/polling/pollingManagerSS.js +15 -15
- package/esm/sync/polling/syncTasks/segmentsSyncTask.js +3 -2
- package/esm/sync/polling/syncTasks/splitsSyncTask.js +9 -0
- package/esm/sync/polling/updaters/mySegmentsUpdater.js +3 -3
- package/esm/sync/polling/updaters/segmentChangesUpdater.js +7 -7
- package/esm/sync/polling/updaters/{definitionChangesUpdater.js → splitChangesUpdater.js} +68 -65
- package/esm/sync/streaming/AuthClient/index.js +1 -1
- package/esm/sync/streaming/SSEHandler/NotificationKeeper.js +2 -2
- package/esm/sync/streaming/SSEHandler/index.js +2 -2
- package/esm/sync/streaming/UpdateWorkers/{DefinitionsUpdateWorker.js → SplitsUpdateWorker.js} +18 -15
- package/esm/sync/streaming/constants.js +2 -2
- package/esm/sync/streaming/parseUtils.js +9 -9
- package/esm/sync/streaming/pushManager.js +18 -18
- package/esm/sync/submitters/eventsSubmitter.js +1 -1
- package/esm/sync/submitters/impressionCountsSubmitter.js +1 -1
- package/esm/sync/submitters/impressionsSubmitter.js +4 -5
- package/esm/sync/submitters/telemetrySubmitter.js +4 -3
- package/esm/sync/submitters/uniqueKeysSubmitter.js +1 -1
- package/esm/sync/syncManagerOnline.js +6 -11
- package/esm/utils/Backoff.js +0 -20
- package/esm/utils/inputValidation/index.js +3 -3
- package/esm/utils/inputValidation/isOperational.js +4 -4
- package/esm/utils/inputValidation/{definition.js → split.js} +8 -8
- package/esm/utils/inputValidation/splitExistence.js +15 -0
- package/esm/utils/inputValidation/splits.js +21 -0
- package/esm/utils/labels/index.js +2 -2
- package/esm/utils/settingsValidation/index.js +0 -2
- package/esm/utils/settingsValidation/splitFilters.js +3 -3
- package/esm/utils/settingsValidation/url.js +2 -6
- package/package.json +6 -7
- package/src/dtos/types.ts +1 -1
- package/src/evaluator/Engine.ts +3 -3
- package/src/evaluator/condition/index.ts +2 -2
- package/src/evaluator/index.ts +27 -35
- package/src/evaluator/types.ts +2 -6
- package/src/presets/serverSide.ts +3 -3
- package/src/sdkClient/client.ts +22 -24
- package/src/sdkClient/sdkLifecycle.ts +3 -0
- package/src/services/authProvider.ts +41 -19
- package/src/services/secureSplitHttpClient.ts +10 -18
- package/src/services/serviceApi.ts +27 -24
- package/src/services/splitApi.ts +10 -9
- package/src/services/types.ts +5 -4
- package/src/storages/inRedis/RedisAdapter.ts +8 -5
- package/src/sync/polling/pollingManagerCS.ts +80 -78
- package/src/sync/polling/pollingManagerSS.ts +49 -45
- package/src/sync/polling/updaters/definitionChangesUpdater.ts +3 -3
- package/src/sync/polling/updaters/segmentChangesUpdater.ts +1 -1
- package/src/sync/streaming/AuthClient/index.ts +14 -15
- package/src/sync/streaming/AuthClient/types.ts +9 -13
- package/src/sync/streaming/SSEClient/index.ts +2 -2
- package/src/sync/streaming/SSEClient/types.ts +2 -2
- package/src/sync/streaming/SSEHandler/index.ts +2 -1
- package/src/sync/streaming/SSEHandler/types.ts +2 -2
- package/src/sync/streaming/constants.ts +1 -0
- package/src/sync/streaming/pushManager.ts +32 -42
- package/src/sync/streaming/types.ts +3 -2
- package/src/sync/submitters/impressionsSubmitter.ts +3 -3
- package/src/sync/submitters/types.ts +2 -2
- package/src/sync/syncManagerOnline.ts +2 -8
- package/src/utils/Backoff.ts +16 -4
- package/types/splitio.d.ts +5 -4
- package/cjs/platform/browser.js +0 -15
- package/cjs/platform/getEventSource/browser.js +0 -8
- package/cjs/platform/getEventSource/eventsource.js +0 -480
- package/cjs/platform/getEventSource/node.js +0 -26
- package/cjs/platform/getFetch/browser.js +0 -9
- package/cjs/platform/getFetch/node.js +0 -27
- package/cjs/platform/getOptions/node.js +0 -25
- package/cjs/platform/node.js +0 -17
- package/cjs/sdkClient/sdkLifecycle.js +0 -72
- package/cjs/sdkClient/trackMethod.js +0 -56
- package/cjs/services/authProvider.js +0 -67
- package/cjs/services/secureSplitHttpClient.js +0 -39
- package/cjs/services/serviceApi.js +0 -145
- package/cjs/storages/AbstractDefinitionsCacheAsync.js +0 -51
- package/cjs/storages/AbstractDefinitionsCacheSync.js +0 -76
- package/cjs/storages/inLocalStorage/DefinitionsCacheInLocal.js +0 -194
- package/cjs/storages/inMemory/DefinitionsCacheInMemory.js +0 -121
- package/cjs/storages/pluggable/DefinitionsCachePluggable.js +0 -212
- package/cjs/sync/polling/syncTasks/definitionsSyncTask.js +0 -13
- package/cjs/utils/EventEmitter.js +0 -391
- package/cjs/utils/filter/bloomFilter.js +0 -37
- package/cjs/utils/inputValidation/definitions.js +0 -25
- package/cjs/utils/inputValidation/target.js +0 -22
- package/esm/platform/browser.js +0 -12
- package/esm/platform/getEventSource/browser.js +0 -4
- package/esm/platform/getEventSource/eventsource.js +0 -480
- package/esm/platform/getEventSource/node.js +0 -20
- package/esm/platform/getFetch/browser.js +0 -5
- package/esm/platform/getFetch/node.js +0 -22
- package/esm/platform/getOptions/node.js +0 -20
- package/esm/platform/node.js +0 -14
- package/esm/sdkClient/sdkLifecycle.js +0 -68
- package/esm/sdkClient/trackMethod.js +0 -52
- package/esm/services/authProvider.js +0 -63
- package/esm/services/secureSplitHttpClient.js +0 -35
- package/esm/services/serviceApi.js +0 -141
- package/esm/storages/AbstractDefinitionsCacheAsync.js +0 -48
- package/esm/storages/AbstractDefinitionsCacheSync.js +0 -71
- package/esm/storages/inLocalStorage/DefinitionsCacheInLocal.js +0 -191
- package/esm/storages/inMemory/DefinitionsCacheInMemory.js +0 -118
- package/esm/storages/pluggable/DefinitionsCachePluggable.js +0 -209
- package/esm/sync/polling/syncTasks/definitionsSyncTask.js +0 -9
- package/esm/utils/EventEmitter.js +0 -387
- package/esm/utils/filter/bloomFilter.js +0 -33
- package/esm/utils/inputValidation/definitionExistence.js +0 -15
- package/esm/utils/inputValidation/definitions.js +0 -21
- package/esm/utils/inputValidation/target.js +0 -18
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.splitChangesUpdaterFactory = exports.computeMutation = exports.parseSegments = void 0;
|
|
4
4
|
var timeout_1 = require("../../../utils/promise/timeout");
|
|
5
5
|
var constants_1 = require("../../../readiness/constants");
|
|
6
6
|
var constants_2 = require("../../../logger/constants");
|
|
@@ -8,6 +8,16 @@ var lang_1 = require("../../../utils/lang");
|
|
|
8
8
|
var constants_3 = require("../../../utils/constants");
|
|
9
9
|
var sets_1 = require("../../../utils/lang/sets");
|
|
10
10
|
var constants_4 = require("../../streaming/constants");
|
|
11
|
+
// Checks that all registered segments have been fetched (changeNumber !== -1 for every segment).
|
|
12
|
+
// Returns a promise that could be rejected.
|
|
13
|
+
// @TODO review together with Segments and MySegments storage APIs
|
|
14
|
+
function checkAllSegmentsExist(segments) {
|
|
15
|
+
var registeredSegments = Promise.resolve(segments.getRegisteredSegments());
|
|
16
|
+
return registeredSegments.then(function (segmentNames) {
|
|
17
|
+
return Promise.all(segmentNames.map(function (segmentName) { return segments.getChangeNumber(segmentName); }))
|
|
18
|
+
.then(function (changeNumbers) { return changeNumbers.every(function (changeNumber) { return changeNumber !== undefined; }); });
|
|
19
|
+
});
|
|
20
|
+
}
|
|
11
21
|
/**
|
|
12
22
|
* Collect segments from a raw FF or RBS definition.
|
|
13
23
|
* Exported for testing purposes.
|
|
@@ -37,118 +47,111 @@ function parseSegments(ruleEntity, matcherType) {
|
|
|
37
47
|
}
|
|
38
48
|
exports.parseSegments = parseSegments;
|
|
39
49
|
/**
|
|
40
|
-
* If there are defined filters and one
|
|
50
|
+
* If there are defined filters and one feature flag doesn't match with them, its status is changed to 'ARCHIVE' to avoid storing it
|
|
41
51
|
* If there is `bySet` filter, `byName` and `byPrefix` filters are ignored
|
|
42
52
|
*
|
|
43
|
-
* @param
|
|
53
|
+
* @param featureFlag - feature flag to be evaluated
|
|
44
54
|
* @param filters - splitFiltersValidation bySet | byName
|
|
45
55
|
*/
|
|
46
|
-
function matchFilters(
|
|
56
|
+
function matchFilters(featureFlag, filters) {
|
|
47
57
|
var _a = filters.groupedFilters, setsFilter = _a.bySet, namesFilter = _a.byName, prefixFilter = _a.byPrefix;
|
|
48
58
|
if (setsFilter.length > 0)
|
|
49
|
-
return
|
|
59
|
+
return featureFlag.sets && featureFlag.sets.some(function (featureFlagSet) { return setsFilter.indexOf(featureFlagSet) > -1; });
|
|
50
60
|
var namesFilterConfigured = namesFilter.length > 0;
|
|
51
61
|
var prefixFilterConfigured = prefixFilter.length > 0;
|
|
52
62
|
if (!namesFilterConfigured && !prefixFilterConfigured)
|
|
53
63
|
return true;
|
|
54
|
-
var matchNames = namesFilterConfigured && namesFilter.indexOf(
|
|
55
|
-
var matchPrefix = prefixFilterConfigured && prefixFilter.some(function (prefix) { return (0, lang_1.startsWith)(
|
|
64
|
+
var matchNames = namesFilterConfigured && namesFilter.indexOf(featureFlag.name) > -1;
|
|
65
|
+
var matchPrefix = prefixFilterConfigured && prefixFilter.some(function (prefix) { return (0, lang_1.startsWith)(featureFlag.name, prefix); });
|
|
56
66
|
return matchNames || matchPrefix;
|
|
57
67
|
}
|
|
58
68
|
/**
|
|
59
|
-
* Given the list of
|
|
60
|
-
* i.e., an object with added
|
|
69
|
+
* Given the list of splits from /splitChanges endpoint, it returns the mutations,
|
|
70
|
+
* i.e., an object with added splits, removed splits and used segments.
|
|
61
71
|
* Exported for testing purposes.
|
|
62
72
|
*/
|
|
63
|
-
function computeMutation(
|
|
64
|
-
return
|
|
65
|
-
if (!filters || matchFilters(ruleEntity, filters)) {
|
|
66
|
-
accum.
|
|
73
|
+
function computeMutation(rules, segments, filters) {
|
|
74
|
+
return rules.reduce(function (accum, ruleEntity) {
|
|
75
|
+
if (ruleEntity.status !== 'ARCHIVED' && (!filters || matchFilters(ruleEntity, filters))) {
|
|
76
|
+
accum.added.push(ruleEntity);
|
|
67
77
|
parseSegments(ruleEntity).forEach(function (segmentName) {
|
|
68
78
|
segments.add(segmentName);
|
|
69
79
|
});
|
|
70
80
|
}
|
|
71
81
|
else {
|
|
72
|
-
accum.removed.push(ruleEntity
|
|
82
|
+
accum.removed.push(ruleEntity);
|
|
73
83
|
}
|
|
74
84
|
accum.names.push(ruleEntity.name);
|
|
75
85
|
return accum;
|
|
76
|
-
}, {
|
|
86
|
+
}, { added: [], removed: [], names: [] });
|
|
77
87
|
}
|
|
78
88
|
exports.computeMutation = computeMutation;
|
|
79
|
-
function convertInstantUpdateToDefinitionChanges(instantUpdate) {
|
|
80
|
-
var payload = instantUpdate.payload, changeNumber = instantUpdate.changeNumber;
|
|
81
|
-
return payload.status === 'ARCHIVED' ?
|
|
82
|
-
{ till: changeNumber, updated: [], removed: [payload.name] } :
|
|
83
|
-
{ till: changeNumber, updated: [payload], removed: [] };
|
|
84
|
-
}
|
|
85
89
|
/**
|
|
86
|
-
*
|
|
87
|
-
* - fetches
|
|
88
|
-
* - updates
|
|
89
|
-
* - uses `
|
|
90
|
+
* factory of SplitChanges updater, a task that:
|
|
91
|
+
* - fetches split changes using `splitChangesFetcher`
|
|
92
|
+
* - updates `splitsCache`
|
|
93
|
+
* - uses `splitsEventEmitter` to emit events related to split data updates
|
|
90
94
|
*
|
|
91
95
|
* @param log - Logger instance
|
|
92
|
-
* @param
|
|
93
|
-
* @param
|
|
96
|
+
* @param splitChangesFetcher - Fetcher of `/splitChanges`
|
|
97
|
+
* @param splits - Splits storage, with sync or async methods
|
|
94
98
|
* @param segments - Segments storage, with sync or async methods
|
|
95
|
-
* @param
|
|
99
|
+
* @param splitsEventEmitter - Optional readiness manager. Not required for synchronizer or producer mode.
|
|
96
100
|
* @param requestTimeoutBeforeReady - How long the updater will wait for the request to timeout. Default 0, i.e., never timeout.
|
|
97
|
-
* @param retriesOnFailureBeforeReady - How many retries on `/splitChanges`
|
|
101
|
+
* @param retriesOnFailureBeforeReady - How many retries on `/splitChanges` we the updater do in case of failure or timeout. Default 0, i.e., no retries.
|
|
98
102
|
*/
|
|
99
|
-
function
|
|
100
|
-
) {
|
|
103
|
+
function splitChangesUpdaterFactory(log, splitChangesFetcher, storage, splitFiltersValidation, splitsEventEmitter, requestTimeoutBeforeReady, retriesOnFailureBeforeReady, isClientSide) {
|
|
101
104
|
if (requestTimeoutBeforeReady === void 0) { requestTimeoutBeforeReady = 0; }
|
|
102
105
|
if (retriesOnFailureBeforeReady === void 0) { retriesOnFailureBeforeReady = 0; }
|
|
103
|
-
var
|
|
106
|
+
var splits = storage.splits, rbSegments = storage.rbSegments, segments = storage.segments;
|
|
104
107
|
var startingUp = true;
|
|
105
|
-
/** timeout decorator for `
|
|
108
|
+
/** timeout decorator for `splitChangesFetcher` promise */
|
|
106
109
|
function _promiseDecorator(promise) {
|
|
107
110
|
if (startingUp && requestTimeoutBeforeReady)
|
|
108
111
|
promise = (0, timeout_1.timeout)(requestTimeoutBeforeReady, promise);
|
|
109
112
|
return promise;
|
|
110
113
|
}
|
|
111
114
|
/**
|
|
112
|
-
*
|
|
115
|
+
* SplitChanges updater returns a promise that resolves with a `false` boolean value if it fails to fetch splits or synchronize them with the storage.
|
|
113
116
|
* Returned promise will not be rejected.
|
|
114
117
|
*
|
|
115
118
|
* @param noCache - true to revalidate data to fetch
|
|
116
119
|
* @param till - query param to bypass CDN requests
|
|
117
120
|
*/
|
|
118
|
-
return function
|
|
121
|
+
return function splitChangesUpdater(noCache, till, instantUpdate) {
|
|
119
122
|
/**
|
|
120
|
-
* @param since - current changeNumber at
|
|
123
|
+
* @param since - current changeNumber at splitsCache
|
|
121
124
|
* @param retry - current number of retry attempts
|
|
122
125
|
*/
|
|
123
|
-
function
|
|
126
|
+
function _splitChangesUpdater(sinces, retry) {
|
|
124
127
|
if (retry === void 0) { retry = 0; }
|
|
125
128
|
var since = sinces[0], rbSince = sinces[1];
|
|
126
|
-
log.debug(constants_2.
|
|
129
|
+
log.debug(constants_2.SYNC_SPLITS_FETCH, sinces);
|
|
127
130
|
return Promise.resolve(instantUpdate ?
|
|
128
131
|
instantUpdate.type === constants_4.SPLIT_UPDATE ?
|
|
129
|
-
// IFFU edge case: a change to
|
|
132
|
+
// IFFU edge case: a change to a flag that adds an IN_RULE_BASED_SEGMENT matcher that is not present yet
|
|
130
133
|
Promise.resolve(rbSegments.contains(parseSegments(instantUpdate.payload, constants_3.IN_RULE_BASED_SEGMENT))).then(function (contains) {
|
|
131
134
|
return contains ?
|
|
132
|
-
{ d:
|
|
133
|
-
|
|
135
|
+
{ ff: { d: [instantUpdate.payload], t: instantUpdate.changeNumber } } :
|
|
136
|
+
splitChangesFetcher(since, noCache, till, rbSince, _promiseDecorator);
|
|
134
137
|
}) :
|
|
135
|
-
{ rbs:
|
|
136
|
-
|
|
137
|
-
.then(function (
|
|
138
|
+
{ rbs: { d: [instantUpdate.payload], t: instantUpdate.changeNumber } } :
|
|
139
|
+
splitChangesFetcher(since, noCache, till, rbSince, _promiseDecorator))
|
|
140
|
+
.then(function (splitChanges) {
|
|
138
141
|
var usedSegments = new Set();
|
|
139
|
-
var
|
|
142
|
+
var updatedFlags = [];
|
|
140
143
|
var ffUpdate = false;
|
|
141
|
-
if (
|
|
142
|
-
var _a = computeMutation(
|
|
143
|
-
|
|
144
|
-
log.debug(constants_2.
|
|
145
|
-
ffUpdate =
|
|
144
|
+
if (splitChanges.ff) {
|
|
145
|
+
var _a = computeMutation(splitChanges.ff.d || [], usedSegments, splitFiltersValidation), added = _a.added, removed = _a.removed, names = _a.names;
|
|
146
|
+
updatedFlags = names;
|
|
147
|
+
log.debug(constants_2.SYNC_SPLITS_UPDATE, [added.length, removed.length]);
|
|
148
|
+
ffUpdate = splits.update(added, removed, splitChanges.ff.t);
|
|
146
149
|
}
|
|
147
150
|
var rbsUpdate = false;
|
|
148
|
-
if (
|
|
149
|
-
var _b = computeMutation(
|
|
150
|
-
log.debug(constants_2.
|
|
151
|
-
rbsUpdate = rbSegments.update(
|
|
151
|
+
if (splitChanges.rbs) {
|
|
152
|
+
var _b = computeMutation(splitChanges.rbs.d || [], usedSegments), added = _b.added, removed = _b.removed;
|
|
153
|
+
log.debug(constants_2.SYNC_RBS_UPDATE, [added.length, removed.length]);
|
|
154
|
+
rbsUpdate = rbSegments.update(added, removed, splitChanges.rbs.t);
|
|
152
155
|
}
|
|
153
156
|
return Promise.all([ffUpdate, rbsUpdate,
|
|
154
157
|
// @TODO if at least 1 segment fetch fails due to 404 and other segments are updated in the storage, SDK_UPDATE is not emitted
|
|
@@ -158,18 +161,18 @@ function definitionChangesUpdaterFactory(log, definitionChangesFetcher, storage,
|
|
|
158
161
|
if (storage.save)
|
|
159
162
|
storage.save();
|
|
160
163
|
startingUp = false;
|
|
161
|
-
if (
|
|
162
|
-
// To emit
|
|
163
|
-
return Promise.resolve(!
|
|
164
|
+
if (splitsEventEmitter) {
|
|
165
|
+
// To emit SDK_SPLITS_ARRIVED for server-side SDK, we must check that all registered segments have been fetched
|
|
166
|
+
return Promise.resolve(!splitsEventEmitter.splitsArrived || ((ffChanged || rbsChanged) && (isClientSide || checkAllSegmentsExist(segments))))
|
|
164
167
|
.catch(function () { return false; } /** noop. just to handle a possible `checkAllSegmentsExist` rejection, before emitting SDK event */)
|
|
165
168
|
.then(function (emitSplitsArrivedEvent) {
|
|
166
169
|
// emit SDK events
|
|
167
170
|
if (emitSplitsArrivedEvent) {
|
|
168
171
|
var metadata = {
|
|
169
|
-
type:
|
|
170
|
-
names:
|
|
172
|
+
type: updatedFlags.length > 0 ? constants_1.FLAGS_UPDATE : constants_1.SEGMENTS_UPDATE,
|
|
173
|
+
names: updatedFlags.length > 0 ? updatedFlags : []
|
|
171
174
|
};
|
|
172
|
-
|
|
175
|
+
splitsEventEmitter.emit(constants_1.SDK_SPLITS_ARRIVED, metadata);
|
|
173
176
|
}
|
|
174
177
|
return true;
|
|
175
178
|
});
|
|
@@ -180,18 +183,18 @@ function definitionChangesUpdaterFactory(log, definitionChangesFetcher, storage,
|
|
|
180
183
|
.catch(function (error) {
|
|
181
184
|
if (startingUp && retriesOnFailureBeforeReady > retry) {
|
|
182
185
|
retry += 1;
|
|
183
|
-
log.warn(constants_2.
|
|
184
|
-
return
|
|
186
|
+
log.warn(constants_2.SYNC_SPLITS_FETCH_RETRY, [retry, error]);
|
|
187
|
+
return _splitChangesUpdater(sinces, retry);
|
|
185
188
|
}
|
|
186
189
|
else {
|
|
187
190
|
startingUp = false;
|
|
188
|
-
log.warn(constants_2.
|
|
191
|
+
log.warn(constants_2.SYNC_SPLITS_FETCH_FAILS, [error]);
|
|
189
192
|
}
|
|
190
193
|
return false;
|
|
191
194
|
});
|
|
192
195
|
}
|
|
193
196
|
// `getChangeNumber` never rejects or throws error
|
|
194
|
-
return Promise.all([
|
|
197
|
+
return Promise.all([splits.getChangeNumber(), rbSegments.getChangeNumber()]).then(_splitChangesUpdater);
|
|
195
198
|
};
|
|
196
199
|
}
|
|
197
|
-
exports.
|
|
200
|
+
exports.splitChangesUpdaterFactory = splitChangesUpdaterFactory;
|
|
@@ -8,7 +8,7 @@ var murmur3_1 = require("../../../utils/murmur3/murmur3");
|
|
|
8
8
|
/**
|
|
9
9
|
* Factory of authentication function.
|
|
10
10
|
*
|
|
11
|
-
* @param fetchAuth - `
|
|
11
|
+
* @param fetchAuth - `SplitAPI.fetchAuth` endpoint
|
|
12
12
|
*/
|
|
13
13
|
function authenticateFactory(fetchAuth) {
|
|
14
14
|
/**
|
|
@@ -73,7 +73,7 @@ function notificationKeeperFactory(pushEmitter, telemetryTracker) {
|
|
|
73
73
|
c.cTime = timestamp;
|
|
74
74
|
if (controlType === constants_2.ControlType.STREAMING_DISABLED) {
|
|
75
75
|
telemetryTracker.streamingEvent(constants_1.STREAMING_STATUS, constants_1.DISABLED);
|
|
76
|
-
pushEmitter.emit(constants_2.
|
|
76
|
+
pushEmitter.emit(constants_2.PUSH_NONRETRYABLE_ERROR);
|
|
77
77
|
}
|
|
78
78
|
else if (hasPublishers) {
|
|
79
79
|
if (controlType === constants_2.ControlType.STREAMING_PAUSED && hasResumed) {
|
|
@@ -51,7 +51,7 @@ function SSEHandlerFactory(log, pushEmitter, telemetryTracker) {
|
|
|
51
51
|
pushEmitter.emit(constants_1.PUSH_RETRYABLE_ERROR);
|
|
52
52
|
}
|
|
53
53
|
else {
|
|
54
|
-
pushEmitter.emit(constants_1.
|
|
54
|
+
pushEmitter.emit(constants_1.PUSH_NONRETRYABLE_ERROR);
|
|
55
55
|
}
|
|
56
56
|
},
|
|
57
57
|
/* NotificationProcessor */
|
package/cjs/sync/streaming/UpdateWorkers/{DefinitionsUpdateWorker.js → SplitsUpdateWorker.js}
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.SplitsUpdateWorker = void 0;
|
|
4
4
|
var constants_1 = require("../../../logger/constants");
|
|
5
5
|
var constants_2 = require("../../../readiness/constants");
|
|
6
6
|
var Backoff_1 = require("../../../utils/Backoff");
|
|
@@ -9,32 +9,35 @@ var constants_4 = require("../constants");
|
|
|
9
9
|
var parseUtils_1 = require("../parseUtils");
|
|
10
10
|
var constants_5 = require("./constants");
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
12
|
+
* SplitsUpdateWorker factory
|
|
13
13
|
*/
|
|
14
|
-
function
|
|
15
|
-
var ff =
|
|
16
|
-
var rbs =
|
|
17
|
-
function
|
|
14
|
+
function SplitsUpdateWorker(log, storage, splitsSyncTask, splitsEventEmitter, telemetryTracker, segmentsSyncTask) {
|
|
15
|
+
var ff = SplitsUpdateWorker(storage.splits);
|
|
16
|
+
var rbs = SplitsUpdateWorker(storage.rbSegments);
|
|
17
|
+
function SplitsUpdateWorker(cache) {
|
|
18
18
|
var maxChangeNumber = -1;
|
|
19
19
|
var handleNewEvent = false;
|
|
20
20
|
var isHandlingEvent;
|
|
21
21
|
var cdnBypass;
|
|
22
22
|
var instantUpdate;
|
|
23
|
-
var backoff = new Backoff_1.Backoff(
|
|
24
|
-
function
|
|
23
|
+
var backoff = new Backoff_1.Backoff(__handleSplitUpdateCall, constants_5.FETCH_BACKOFF_BASE, constants_5.FETCH_BACKOFF_MAX_WAIT);
|
|
24
|
+
function __handleSplitUpdateCall() {
|
|
25
25
|
isHandlingEvent = true;
|
|
26
26
|
if (maxChangeNumber > cache.getChangeNumber()) {
|
|
27
27
|
handleNewEvent = false;
|
|
28
28
|
// fetch splits revalidating data if cached
|
|
29
|
-
|
|
29
|
+
splitsSyncTask.execute(true, cdnBypass ? maxChangeNumber : undefined, instantUpdate).then(function () {
|
|
30
30
|
if (!isHandlingEvent)
|
|
31
31
|
return; // halt if `stop` has been called
|
|
32
32
|
if (handleNewEvent) {
|
|
33
|
-
|
|
33
|
+
__handleSplitUpdateCall();
|
|
34
34
|
}
|
|
35
35
|
else {
|
|
36
36
|
if (instantUpdate)
|
|
37
37
|
telemetryTracker.trackUpdatesFromSSE(constants_3.SPLITS);
|
|
38
|
+
// fetch new registered segments for server-side API. Not retrying on error
|
|
39
|
+
if (segmentsSyncTask)
|
|
40
|
+
segmentsSyncTask.execute(true);
|
|
38
41
|
var attempts = backoff.attempts + 1;
|
|
39
42
|
if (ff.isSync() && rbs.isSync()) {
|
|
40
43
|
log.debug("Refresh completed".concat(cdnBypass ? ' bypassing the CDN' : '', " in ").concat(attempts, " attempts."));
|
|
@@ -52,7 +55,7 @@ function DefinitionsUpdateWorker(log, storage, definitionsSyncTask, definitionsE
|
|
|
52
55
|
else {
|
|
53
56
|
backoff.reset();
|
|
54
57
|
cdnBypass = true;
|
|
55
|
-
|
|
58
|
+
__handleSplitUpdateCall();
|
|
56
59
|
}
|
|
57
60
|
}
|
|
58
61
|
});
|
|
@@ -80,7 +83,7 @@ function DefinitionsUpdateWorker(log, storage, definitionsSyncTask, definitionsE
|
|
|
80
83
|
instantUpdate = { payload: payload, changeNumber: changeNumber, type: type };
|
|
81
84
|
}
|
|
82
85
|
if (backoff.timeoutID || !isHandlingEvent)
|
|
83
|
-
|
|
86
|
+
__handleSplitUpdateCall();
|
|
84
87
|
backoff.reset();
|
|
85
88
|
},
|
|
86
89
|
stop: function () {
|
|
@@ -115,11 +118,11 @@ function DefinitionsUpdateWorker(log, storage, definitionsSyncTask, definitionsE
|
|
|
115
118
|
* @param splitName - name of split to kill
|
|
116
119
|
* @param defaultTreatment - default treatment value
|
|
117
120
|
*/
|
|
118
|
-
|
|
121
|
+
killSplit: function (_a) {
|
|
119
122
|
var changeNumber = _a.changeNumber, splitName = _a.splitName, defaultTreatment = _a.defaultTreatment;
|
|
120
|
-
if (storage.
|
|
123
|
+
if (storage.splits.killLocally(splitName, defaultTreatment, changeNumber)) {
|
|
121
124
|
// trigger an SDK_UPDATE if Split was killed locally
|
|
122
|
-
|
|
125
|
+
splitsEventEmitter.emit(constants_2.SDK_SPLITS_ARRIVED, true);
|
|
123
126
|
}
|
|
124
127
|
// queues the SplitChanges fetch (only if changeNumber is newer)
|
|
125
128
|
ff.put({ changeNumber: changeNumber });
|
|
@@ -130,4 +133,4 @@ function DefinitionsUpdateWorker(log, storage, definitionsSyncTask, definitionsE
|
|
|
130
133
|
}
|
|
131
134
|
};
|
|
132
135
|
}
|
|
133
|
-
exports.
|
|
136
|
+
exports.SplitsUpdateWorker = SplitsUpdateWorker;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ControlType = exports.OCCUPANCY = exports.CONTROL = exports.RB_SEGMENT_UPDATE = exports.SPLIT_UPDATE = exports.SPLIT_KILL = exports.SEGMENT_UPDATE = exports.MEMBERSHIPS_LS_UPDATE = exports.MEMBERSHIPS_MS_UPDATE = exports.PUSH_SUBSYSTEM_DOWN = exports.PUSH_SUBSYSTEM_UP = exports.PUSH_RETRYABLE_ERROR = exports.
|
|
3
|
+
exports.ControlType = exports.OCCUPANCY = exports.CONTROL = exports.RB_SEGMENT_UPDATE = exports.SPLIT_UPDATE = exports.SPLIT_KILL = exports.SEGMENT_UPDATE = exports.MEMBERSHIPS_LS_UPDATE = exports.MEMBERSHIPS_MS_UPDATE = exports.PUSH_SUBSYSTEM_DOWN = exports.PUSH_SUBSYSTEM_UP = exports.PUSH_RETRYABLE_ERROR = exports.PUSH_NONRETRYABLE_ERROR = exports.SECONDS_BEFORE_EXPIRATION = void 0;
|
|
4
4
|
// time for refresh token
|
|
5
5
|
exports.SECONDS_BEFORE_EXPIRATION = 600;
|
|
6
6
|
// Internal SDK events, subscribed by SyncManager and PushManager
|
|
@@ -8,7 +8,7 @@ exports.SECONDS_BEFORE_EXPIRATION = 600;
|
|
|
8
8
|
* emitted on SSE and Authenticate non-recoverable errors, STREAMING_DISABLED control notification and authentication with pushEnabled false
|
|
9
9
|
* triggers `handleNonRetryableError` call
|
|
10
10
|
*/
|
|
11
|
-
exports.
|
|
11
|
+
exports.PUSH_NONRETRYABLE_ERROR = 'PUSH_NONRETRYABLE_ERROR';
|
|
12
12
|
/**
|
|
13
13
|
* emitted on SSE and Authenticate recoverable errors
|
|
14
14
|
* triggers `handleRetryableError` call
|
|
@@ -20,7 +20,7 @@ exports.PUSH_RETRYABLE_ERROR = 'PUSH_RETRYABLE_ERROR';
|
|
|
20
20
|
*/
|
|
21
21
|
exports.PUSH_SUBSYSTEM_UP = 'PUSH_SUBSYSTEM_UP';
|
|
22
22
|
/**
|
|
23
|
-
* emitted on STREAMING_PAUSED control notification, OCCUPANCY equal to 0,
|
|
23
|
+
* emitted on STREAMING_PAUSED control notification, OCCUPANCY equal to 0, PUSH_NONRETRYABLE_ERROR and PUSH_RETRYABLE_ERROR events.
|
|
24
24
|
* triggers `startPolling` and `stopWorkers` calls
|
|
25
25
|
*/
|
|
26
26
|
exports.PUSH_SUBSYSTEM_DOWN = 'PUSH_SUBSYSTEM_DOWN';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getDelay = exports.parseFFUpdatePayload = exports.isInBitmap = exports.parseBitmap = exports.
|
|
3
|
+
exports.getDelay = exports.parseFFUpdatePayload = exports.isInBitmap = exports.parseBitmap = exports.parseKeyList = void 0;
|
|
4
4
|
var decompress_1 = require("../../utils/decompress");
|
|
5
5
|
var base64_1 = require("../../utils/base64");
|
|
6
6
|
var murmur3_1 = require("../../utils/murmur3/murmur3");
|
|
@@ -33,24 +33,24 @@ function decompress(data, compression) {
|
|
|
33
33
|
throw new Error("Invalid compression algorithm #".concat(compression));
|
|
34
34
|
}
|
|
35
35
|
/**
|
|
36
|
-
* Decode, decompress and parse the provided 'data' into
|
|
36
|
+
* Decode, decompress and parse the provided 'data' into a KeyList object
|
|
37
37
|
*
|
|
38
38
|
* @param data - base64 encoded string
|
|
39
39
|
* @param compression - 1 GZIP, 2 ZLIB
|
|
40
40
|
* @param avoidPrecisionLoss - true as default, set it as false if dont need to avoid precission loss
|
|
41
|
-
* @returns
|
|
41
|
+
* @returns keyList
|
|
42
42
|
* @throws if data string cannot be decoded, decompressed or parsed
|
|
43
43
|
*/
|
|
44
|
-
function
|
|
44
|
+
function parseKeyList(data, compression, avoidPrecisionLoss) {
|
|
45
45
|
if (avoidPrecisionLoss === void 0) { avoidPrecisionLoss = true; }
|
|
46
|
-
var
|
|
47
|
-
var
|
|
48
|
-
// replace numbers to strings, to avoid losing precision
|
|
46
|
+
var binKeyList = decompress(data, compression);
|
|
47
|
+
var strKeyList = Uint8ArrayToString(binKeyList);
|
|
48
|
+
// replace numbers to strings, to avoid losing precision
|
|
49
49
|
if (avoidPrecisionLoss)
|
|
50
|
-
|
|
51
|
-
return JSON.parse(
|
|
50
|
+
strKeyList = strKeyList.replace(/\d+/g, '"$&"');
|
|
51
|
+
return JSON.parse(strKeyList);
|
|
52
52
|
}
|
|
53
|
-
exports.
|
|
53
|
+
exports.parseKeyList = parseKeyList;
|
|
54
54
|
/**
|
|
55
55
|
* Decode, decompress and parse the provided 'data' into a Bitmap object
|
|
56
56
|
*
|
|
@@ -83,7 +83,7 @@ exports.isInBitmap = isInBitmap;
|
|
|
83
83
|
*/
|
|
84
84
|
function parseFFUpdatePayload(compression, data) {
|
|
85
85
|
return compression > 0 ?
|
|
86
|
-
|
|
86
|
+
parseKeyList(data, compression, false) :
|
|
87
87
|
JSON.parse((0, base64_1.decodeFromBase64)(data));
|
|
88
88
|
}
|
|
89
89
|
exports.parseFFUpdatePayload = parseFFUpdatePayload;
|
|
@@ -6,7 +6,7 @@ var Backoff_1 = require("../../utils/Backoff");
|
|
|
6
6
|
var SSEHandler_1 = require("./SSEHandler");
|
|
7
7
|
var MySegmentsUpdateWorker_1 = require("./UpdateWorkers/MySegmentsUpdateWorker");
|
|
8
8
|
var SegmentsUpdateWorker_1 = require("./UpdateWorkers/SegmentsUpdateWorker");
|
|
9
|
-
var
|
|
9
|
+
var SplitsUpdateWorker_1 = require("./UpdateWorkers/SplitsUpdateWorker");
|
|
10
10
|
var AuthClient_1 = require("./AuthClient");
|
|
11
11
|
var lang_1 = require("../../utils/lang");
|
|
12
12
|
var SSEClient_1 = require("./SSEClient");
|
|
@@ -23,7 +23,7 @@ var constants_3 = require("../../utils/constants");
|
|
|
23
23
|
* - for client-side, with support for multiple clients, if key is provided in settings
|
|
24
24
|
*/
|
|
25
25
|
function pushManagerFactory(params, pollingManager) {
|
|
26
|
-
var settings = params.settings, storage = params.storage,
|
|
26
|
+
var settings = params.settings, storage = params.storage, splitApi = params.splitApi, readiness = params.readiness, platform = params.platform, telemetryTracker = params.telemetryTracker;
|
|
27
27
|
// `userKey` is the matching key of main client in client-side SDK.
|
|
28
28
|
// It can be used to check if running on client-side or server-side SDK.
|
|
29
29
|
var userKey = (0, key_1.checkIfServerSide)(settings) ? undefined : (0, key_1.getMatching)(settings.core.key);
|
|
@@ -37,7 +37,7 @@ function pushManagerFactory(params, pollingManager) {
|
|
|
37
37
|
log.warn(constants_2.STREAMING_FALLBACK, [e]);
|
|
38
38
|
return;
|
|
39
39
|
}
|
|
40
|
-
var authenticate = (0, AuthClient_1.authenticateFactory)(
|
|
40
|
+
var authenticate = (0, AuthClient_1.authenticateFactory)(splitApi.fetchAuth);
|
|
41
41
|
// init feedback loop
|
|
42
42
|
var pushEmitter = new platform.EventEmitter();
|
|
43
43
|
var sseHandler = (0, SSEHandler_1.SSEHandlerFactory)(log, pushEmitter, telemetryTracker);
|
|
@@ -45,8 +45,8 @@ function pushManagerFactory(params, pollingManager) {
|
|
|
45
45
|
// init workers
|
|
46
46
|
// MySegmentsUpdateWorker (client-side) are initiated in `add` method
|
|
47
47
|
var segmentsUpdateWorker = userKey ? undefined : (0, SegmentsUpdateWorker_1.SegmentsUpdateWorker)(log, pollingManager.segmentsSyncTask, storage.segments);
|
|
48
|
-
// For server-side we pass the segmentsSyncTask, used by
|
|
49
|
-
var
|
|
48
|
+
// For server-side we pass the segmentsSyncTask, used by SplitsUpdateWorker to fetch new segments
|
|
49
|
+
var splitsUpdateWorker = (0, SplitsUpdateWorker_1.SplitsUpdateWorker)(log, storage, pollingManager.splitsSyncTask, readiness.splits, telemetryTracker, userKey ? undefined : pollingManager.segmentsSyncTask);
|
|
50
50
|
// [Only for client-side] map of hashes to user keys, to dispatch membership update events to the corresponding MySegmentsUpdateWorker
|
|
51
51
|
var userKeyHashes = {};
|
|
52
52
|
// [Only for client-side] map of user keys to their corresponding hash64 and MySegmentsUpdateWorkers.
|
|
@@ -54,10 +54,10 @@ function pushManagerFactory(params, pollingManager) {
|
|
|
54
54
|
var clients = {};
|
|
55
55
|
// [Only for client-side] variable to flag that a new client was added. It is needed to reconnect streaming.
|
|
56
56
|
var connectForNewClient = false;
|
|
57
|
-
// flag that indicates if `stop/disconnectPush` was called, either by the SyncManager, when the client is destroyed, or due to a
|
|
57
|
+
// flag that indicates if `stop/disconnectPush` was called, either by the SyncManager, when the client is destroyed, or due to a PUSH_NONRETRYABLE_ERROR error.
|
|
58
58
|
// It is used to halt the `connectPush` process if it was in progress.
|
|
59
59
|
var disconnected;
|
|
60
|
-
// flag that indicates a
|
|
60
|
+
// flag that indicates a PUSH_NONRETRYABLE_ERROR, condition with which starting pushManager again is ignored.
|
|
61
61
|
// true if STREAMING_DISABLED control event, or 'pushEnabled: false', or non-recoverable SSE or Auth errors.
|
|
62
62
|
var disabled; // `disabled` implies `disconnected === true`
|
|
63
63
|
/** PushManager functions related to initialization */
|
|
@@ -96,11 +96,11 @@ function pushManagerFactory(params, pollingManager) {
|
|
|
96
96
|
authenticate(userKeys).then(function (authData) {
|
|
97
97
|
if (disconnected)
|
|
98
98
|
return;
|
|
99
|
-
// 'pushEnabled: false' is handled as a
|
|
99
|
+
// 'pushEnabled: false' is handled as a PUSH_NONRETRYABLE_ERROR instead of PUSH_SUBSYSTEM_DOWN, in order to
|
|
100
100
|
// close the sseClient in case the org has been bloqued while the instance was connected to streaming
|
|
101
101
|
if (!authData.pushEnabled) {
|
|
102
102
|
log.info(constants_2.STREAMING_DISABLED);
|
|
103
|
-
pushEmitter.emit(constants_1.
|
|
103
|
+
pushEmitter.emit(constants_1.PUSH_NONRETRYABLE_ERROR);
|
|
104
104
|
return;
|
|
105
105
|
}
|
|
106
106
|
// [Only for client-side] don't open SSE connection if a new shared client was added, since it means that a new authentication is taking place
|
|
@@ -115,7 +115,7 @@ function pushManagerFactory(params, pollingManager) {
|
|
|
115
115
|
// Handle 4XX HTTP errors: 401 (invalid SDK Key) or 400 (using incorrect SDK Key, i.e., client-side SDK Key on server-side)
|
|
116
116
|
if (error.statusCode >= 400 && error.statusCode < 500) {
|
|
117
117
|
telemetryTracker.streamingEvent(constants_3.AUTH_REJECTION);
|
|
118
|
-
pushEmitter.emit(constants_1.
|
|
118
|
+
pushEmitter.emit(constants_1.PUSH_NONRETRYABLE_ERROR);
|
|
119
119
|
return;
|
|
120
120
|
}
|
|
121
121
|
// Handle other HTTP and network errors as recoverable errors
|
|
@@ -139,7 +139,7 @@ function pushManagerFactory(params, pollingManager) {
|
|
|
139
139
|
}
|
|
140
140
|
// cancel scheduled fetch retries of Splits, Segments, and MySegments Update Workers
|
|
141
141
|
function stopWorkers() {
|
|
142
|
-
|
|
142
|
+
splitsUpdateWorker.stop();
|
|
143
143
|
if (userKey)
|
|
144
144
|
(0, lang_1.forOwn)(clients, function (_a) {
|
|
145
145
|
var worker = _a.worker;
|
|
@@ -155,7 +155,7 @@ function pushManagerFactory(params, pollingManager) {
|
|
|
155
155
|
connectPushRetryBackoff.reset();
|
|
156
156
|
});
|
|
157
157
|
/** Fallback to polling without retry due to: STREAMING_DISABLED control event, or 'pushEnabled: false', or non-recoverable SSE and Authentication errors */
|
|
158
|
-
pushEmitter.on(constants_1.
|
|
158
|
+
pushEmitter.on(constants_1.PUSH_NONRETRYABLE_ERROR, function handleNonRetryableError() {
|
|
159
159
|
disabled = true;
|
|
160
160
|
// Note: `stopWorkers` is been called twice, but it is not harmful
|
|
161
161
|
disconnectPush();
|
|
@@ -181,9 +181,9 @@ function pushManagerFactory(params, pollingManager) {
|
|
|
181
181
|
connectPush();
|
|
182
182
|
});
|
|
183
183
|
/** Functions related to synchronization (Queues and Workers in the spec) */
|
|
184
|
-
pushEmitter.on(constants_1.SPLIT_KILL,
|
|
185
|
-
pushEmitter.on(constants_1.SPLIT_UPDATE,
|
|
186
|
-
pushEmitter.on(constants_1.RB_SEGMENT_UPDATE,
|
|
184
|
+
pushEmitter.on(constants_1.SPLIT_KILL, splitsUpdateWorker.killSplit);
|
|
185
|
+
pushEmitter.on(constants_1.SPLIT_UPDATE, splitsUpdateWorker.put);
|
|
186
|
+
pushEmitter.on(constants_1.RB_SEGMENT_UPDATE, splitsUpdateWorker.put);
|
|
187
187
|
function handleMySegmentsUpdate(parsedData) {
|
|
188
188
|
switch (parsedData.u) {
|
|
189
189
|
case types_1.UpdateStrategy.BoundedFetchRequest: {
|
|
@@ -206,7 +206,7 @@ function pushManagerFactory(params, pollingManager) {
|
|
|
206
206
|
case types_1.UpdateStrategy.KeyList: {
|
|
207
207
|
var keyList = void 0, added_1, removed_1;
|
|
208
208
|
try {
|
|
209
|
-
keyList = (0, parseUtils_1.
|
|
209
|
+
keyList = (0, parseUtils_1.parseKeyList)(parsedData.d, parsedData.c);
|
|
210
210
|
added_1 = new Set(keyList.a);
|
|
211
211
|
removed_1 = new Set(keyList.r);
|
|
212
212
|
}
|
|
@@ -7,7 +7,7 @@ var constants_1 = require("../../logger/constants");
|
|
|
7
7
|
* Submitter that periodically posts tracked events
|
|
8
8
|
*/
|
|
9
9
|
function eventsSubmitterFactory(params) {
|
|
10
|
-
var _a = params.settings, log = _a.log, eventsPushRate = _a.scheduler.eventsPushRate, eventsFirstPushWindow = _a.startup.eventsFirstPushWindow, postEventsBulk = params.
|
|
10
|
+
var _a = params.settings, log = _a.log, eventsPushRate = _a.scheduler.eventsPushRate, eventsFirstPushWindow = _a.startup.eventsFirstPushWindow, postEventsBulk = params.splitApi.postEventsBulk, events = params.storage.events;
|
|
11
11
|
// don't retry events.
|
|
12
12
|
var submitter = (0, submitter_1.submitterFactory)(log, postEventsBulk, events, eventsPushRate);
|
|
13
13
|
// Set a timer for the first push window of events.
|
|
@@ -29,7 +29,7 @@ var IMPRESSIONS_COUNT_RATE = 1800000; // 30 minutes
|
|
|
29
29
|
* Submitter that periodically posts impression counts
|
|
30
30
|
*/
|
|
31
31
|
function impressionCountsSubmitterFactory(params) {
|
|
32
|
-
var log = params.settings.log, postTestImpressionsCount = params.
|
|
32
|
+
var log = params.settings.log, postTestImpressionsCount = params.splitApi.postTestImpressionsCount, impressionCounts = params.storage.impressionCounts;
|
|
33
33
|
// retry impressions counts only once.
|
|
34
34
|
return (0, submitter_1.submitterFactory)(log, postTestImpressionsCount, impressionCounts, IMPRESSIONS_COUNT_RATE, fromImpressionCountsCollector, 1);
|
|
35
35
|
}
|
|
@@ -14,7 +14,7 @@ function fromImpressionsCollector(sendLabels, data) {
|
|
|
14
14
|
dto.push({
|
|
15
15
|
f: name,
|
|
16
16
|
i: value.map(function (entry) {
|
|
17
|
-
|
|
17
|
+
var keyImpression = {
|
|
18
18
|
k: entry.keyName,
|
|
19
19
|
t: entry.treatment,
|
|
20
20
|
m: entry.time,
|
|
@@ -22,10 +22,9 @@ function fromImpressionsCollector(sendLabels, data) {
|
|
|
22
22
|
r: sendLabels ? entry.label : undefined,
|
|
23
23
|
b: entry.bucketingKey,
|
|
24
24
|
pt: entry.pt,
|
|
25
|
-
properties: entry.properties
|
|
26
|
-
// @ts-expect-error - entityType is not yet public. @TODO: add to SplitIO.ImpressionDTO type
|
|
27
|
-
et: entry.entityType, // Definition type
|
|
25
|
+
properties: entry.properties // Properties
|
|
28
26
|
};
|
|
27
|
+
return keyImpression;
|
|
29
28
|
})
|
|
30
29
|
});
|
|
31
30
|
});
|
|
@@ -36,7 +35,7 @@ exports.fromImpressionsCollector = fromImpressionsCollector;
|
|
|
36
35
|
* Submitter that periodically posts impressions data
|
|
37
36
|
*/
|
|
38
37
|
function impressionsSubmitterFactory(params) {
|
|
39
|
-
var _a = params.settings, log = _a.log, impressionsRefreshRate = _a.scheduler.impressionsRefreshRate, labelsEnabled = _a.core.labelsEnabled, postTestImpressionsBulk = params.
|
|
38
|
+
var _a = params.settings, log = _a.log, impressionsRefreshRate = _a.scheduler.impressionsRefreshRate, labelsEnabled = _a.core.labelsEnabled, postTestImpressionsBulk = params.splitApi.postTestImpressionsBulk, impressions = params.storage.impressions;
|
|
40
39
|
// retry impressions only once.
|
|
41
40
|
var syncTask = (0, submitter_1.submitterFactory)(log, postTestImpressionsBulk, impressions, impressionsRefreshRate, fromImpressionsCollector.bind(undefined, labelsEnabled), 1);
|
|
42
41
|
// register impressions submitter to be executed when impressions cache is full
|