@splitsoftware/splitio-commons 3.0.0-rc.0 → 3.0.0-rc.2
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 +8 -3
- package/cjs/evaluator/index.js +11 -11
- package/cjs/logger/constants.js +4 -4
- package/cjs/logger/messages/warn.js +0 -1
- package/cjs/readiness/constants.js +4 -4
- package/cjs/readiness/readinessManager.js +22 -22
- package/cjs/readiness/sdkReadinessManager.js +0 -16
- package/cjs/sdkClient/sdkLifecycle.js +2 -1
- package/cjs/sdkClient/trackMethod.js +2 -2
- package/cjs/sdkFactory/index.js +5 -5
- package/cjs/sdkManager/index.js +2 -2
- package/cjs/services/authProvider.js +67 -0
- package/cjs/services/secureSplitHttpClient.js +39 -0
- package/cjs/services/splitApi.js +15 -6
- package/cjs/storages/AbstractDefinitionsCacheAsync.js +51 -0
- package/cjs/storages/AbstractDefinitionsCacheSync.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/DefinitionsCacheInLocal.js +194 -0
- package/cjs/storages/inLocalStorage/RBSegmentsCacheInLocal.js +9 -9
- package/cjs/storages/inLocalStorage/index.js +6 -6
- package/cjs/storages/inLocalStorage/validateCache.js +3 -3
- package/cjs/storages/inMemory/DefinitionsCacheInMemory.js +121 -0
- package/cjs/storages/inMemory/InMemoryStorage.js +4 -4
- package/cjs/storages/inMemory/InMemoryStorageCS.js +5 -5
- package/cjs/storages/inMemory/RBSegmentsCacheInMemory.js +4 -4
- package/cjs/storages/inMemory/SegmentsCacheInMemory.js +1 -1
- package/cjs/storages/inMemory/TelemetryCacheInMemory.js +3 -3
- package/cjs/storages/inRedis/{SplitsCacheInRedis.js → DefinitionsCacheInRedis.js} +77 -77
- package/cjs/storages/inRedis/index.js +2 -2
- package/cjs/storages/pluggable/DefinitionsCachePluggable.js +212 -0
- package/cjs/storages/pluggable/index.js +2 -2
- package/cjs/storages/setRolloutPlan.js +5 -5
- package/cjs/sync/offline/syncTasks/fromObjectSyncTask.js +5 -5
- package/cjs/sync/polling/fetchers/splitChangesFetcher.js +1 -1
- package/cjs/sync/polling/pollingManagerCS.js +7 -7
- package/cjs/sync/polling/pollingManagerSS.js +3 -3
- package/cjs/sync/polling/syncTasks/definitionsSyncTask.js +1 -1
- package/cjs/sync/polling/syncTasks/segmentsSyncTask.js +2 -3
- package/cjs/sync/polling/updaters/definitionChangesUpdater.js +8 -8
- package/cjs/sync/polling/updaters/mySegmentsUpdater.js +2 -2
- package/cjs/sync/streaming/SSEHandler/NotificationKeeper.js +1 -1
- package/cjs/sync/streaming/SSEHandler/index.js +1 -1
- package/cjs/sync/streaming/UpdateWorkers/{SplitsUpdateWorker.js → DefinitionsUpdateWorker.js} +15 -15
- package/cjs/sync/streaming/constants.js +3 -3
- package/cjs/sync/streaming/pushManager.js +13 -13
- package/cjs/sync/submitters/telemetrySubmitter.js +1 -2
- package/cjs/sync/syncManagerOnline.js +10 -8
- package/cjs/utils/Backoff.js +20 -0
- package/cjs/utils/lang/sets.js +4 -4
- package/cjs/utils/settingsValidation/index.js +2 -0
- package/cjs/utils/settingsValidation/url.js +6 -2
- package/esm/evaluator/index.js +11 -11
- package/esm/logger/constants.js +1 -1
- package/esm/logger/messages/warn.js +0 -1
- package/esm/readiness/constants.js +3 -3
- package/esm/readiness/readinessManager.js +23 -23
- package/esm/readiness/sdkReadinessManager.js +1 -17
- package/esm/sdkClient/sdkLifecycle.js +2 -1
- package/esm/sdkClient/trackMethod.js +2 -2
- package/esm/sdkFactory/index.js +6 -6
- package/esm/sdkManager/index.js +2 -2
- package/esm/services/authProvider.js +63 -0
- package/esm/services/secureSplitHttpClient.js +35 -0
- package/esm/services/splitApi.js +15 -6
- package/esm/storages/AbstractDefinitionsCacheAsync.js +48 -0
- package/esm/storages/AbstractDefinitionsCacheSync.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/DefinitionsCacheInLocal.js +191 -0
- package/esm/storages/inLocalStorage/RBSegmentsCacheInLocal.js +6 -6
- package/esm/storages/inLocalStorage/index.js +6 -6
- package/esm/storages/inLocalStorage/validateCache.js +3 -3
- package/esm/storages/inMemory/DefinitionsCacheInMemory.js +118 -0
- package/esm/storages/inMemory/InMemoryStorage.js +4 -4
- package/esm/storages/inMemory/InMemoryStorageCS.js +5 -5
- package/esm/storages/inMemory/RBSegmentsCacheInMemory.js +1 -1
- package/esm/storages/inMemory/SegmentsCacheInMemory.js +1 -1
- package/esm/storages/inMemory/TelemetryCacheInMemory.js +3 -3
- package/esm/storages/inRedis/{SplitsCacheInRedis.js → DefinitionsCacheInRedis.js} +76 -76
- package/esm/storages/inRedis/index.js +2 -2
- package/esm/storages/pluggable/DefinitionsCachePluggable.js +209 -0
- package/esm/storages/pluggable/index.js +2 -2
- package/esm/storages/setRolloutPlan.js +5 -5
- package/esm/sync/offline/syncTasks/fromObjectSyncTask.js +6 -6
- package/esm/sync/polling/fetchers/splitChangesFetcher.js +1 -1
- package/esm/sync/polling/pollingManagerCS.js +4 -4
- package/esm/sync/polling/pollingManagerSS.js +3 -3
- package/esm/sync/polling/syncTasks/definitionsSyncTask.js +1 -1
- package/esm/sync/polling/syncTasks/segmentsSyncTask.js +2 -3
- package/esm/sync/polling/updaters/definitionChangesUpdater.js +9 -9
- package/esm/sync/polling/updaters/mySegmentsUpdater.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/{SplitsUpdateWorker.js → DefinitionsUpdateWorker.js} +14 -14
- package/esm/sync/streaming/constants.js +2 -2
- package/esm/sync/streaming/pushManager.js +14 -14
- package/esm/sync/submitters/telemetrySubmitter.js +1 -2
- package/esm/sync/syncManagerOnline.js +9 -7
- package/esm/utils/Backoff.js +20 -0
- package/esm/utils/lang/sets.js +4 -4
- package/esm/utils/settingsValidation/index.js +2 -0
- package/esm/utils/settingsValidation/url.js +6 -2
- package/package.json +1 -1
- package/src/dtos/types.ts +2 -2
- package/src/evaluator/index.ts +11 -11
- package/src/logger/constants.ts +1 -1
- package/src/logger/messages/warn.ts +0 -1
- package/src/readiness/constants.ts +3 -3
- package/src/readiness/readinessManager.ts +22 -22
- package/src/readiness/sdkReadinessManager.ts +1 -16
- package/src/readiness/types.ts +10 -16
- package/src/sdkClient/sdkLifecycle.ts +2 -1
- package/src/sdkClient/trackMethod.ts +2 -2
- package/src/sdkFactory/index.ts +5 -5
- package/src/sdkManager/index.ts +6 -6
- package/src/services/authProvider.ts +86 -0
- package/src/services/secureSplitHttpClient.ts +44 -0
- package/src/services/splitApi.ts +18 -7
- package/src/services/types.ts +6 -1
- package/src/storages/AbstractDefinitionsCacheAsync.ts +63 -0
- package/src/storages/AbstractDefinitionsCacheSync.ts +95 -0
- package/src/storages/KeyBuilder.ts +6 -6
- package/src/storages/KeyBuilderCS.ts +6 -6
- package/src/storages/KeyBuilderSS.ts +2 -2
- package/src/storages/getRolloutPlan.ts +3 -3
- package/src/storages/inLocalStorage/DefinitionsCacheInLocal.ts +234 -0
- package/src/storages/inLocalStorage/RBSegmentsCacheInLocal.ts +6 -6
- package/src/storages/inLocalStorage/index.ts +6 -6
- package/src/storages/inLocalStorage/validateCache.ts +4 -4
- package/src/storages/inMemory/DefinitionsCacheInMemory.ts +130 -0
- package/src/storages/inMemory/InMemoryStorage.ts +4 -4
- package/src/storages/inMemory/InMemoryStorageCS.ts +5 -5
- package/src/storages/inMemory/RBSegmentsCacheInMemory.ts +1 -1
- package/src/storages/inMemory/SegmentsCacheInMemory.ts +1 -1
- package/src/storages/inMemory/TelemetryCacheInMemory.ts +3 -3
- package/src/storages/inRedis/{SplitsCacheInRedis.ts → DefinitionsCacheInRedis.ts} +67 -67
- package/src/storages/inRedis/index.ts +2 -2
- package/src/storages/pluggable/DefinitionsCachePluggable.ts +230 -0
- package/src/storages/pluggable/index.ts +2 -2
- package/src/storages/setRolloutPlan.ts +7 -7
- package/src/storages/types.ts +19 -19
- package/src/sync/offline/syncTasks/fromObjectSyncTask.ts +8 -8
- package/src/sync/polling/fetchers/splitChangesFetcher.ts +3 -3
- package/src/sync/polling/pollingManagerCS.ts +4 -4
- package/src/sync/polling/pollingManagerSS.ts +5 -4
- package/src/sync/polling/syncTasks/definitionsSyncTask.ts +1 -1
- package/src/sync/polling/syncTasks/segmentsSyncTask.ts +3 -4
- package/src/sync/polling/types.ts +1 -1
- package/src/sync/polling/updaters/definitionChangesUpdater.ts +11 -11
- package/src/sync/polling/updaters/mySegmentsUpdater.ts +1 -1
- package/src/sync/streaming/AuthClient/index.ts +2 -2
- package/src/sync/streaming/AuthClient/types.ts +14 -11
- package/src/sync/streaming/SSEClient/index.ts +2 -2
- package/src/sync/streaming/SSEClient/types.ts +2 -2
- package/src/sync/streaming/SSEHandler/NotificationKeeper.ts +2 -2
- package/src/sync/streaming/SSEHandler/index.ts +2 -2
- package/src/sync/streaming/UpdateWorkers/{SplitsUpdateWorker.ts → DefinitionsUpdateWorker.ts} +16 -16
- package/src/sync/streaming/constants.ts +2 -2
- package/src/sync/streaming/pushManager.ts +16 -16
- package/src/sync/streaming/types.ts +2 -2
- package/src/sync/submitters/telemetrySubmitter.ts +1 -2
- package/src/sync/syncManagerOnline.ts +10 -8
- package/src/utils/Backoff.ts +21 -0
- package/src/utils/inputValidation/trafficTypeExistence.ts +2 -2
- package/src/utils/jwt/types.ts +1 -1
- package/src/utils/lang/sets.ts +4 -2
- package/src/utils/settingsValidation/index.ts +2 -0
- package/src/utils/settingsValidation/url.ts +6 -2
- package/types/splitio.d.ts +27 -8
- package/cjs/storages/AbstractSplitsCacheAsync.js +0 -51
- package/cjs/storages/AbstractSplitsCacheSync.js +0 -76
- package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +0 -194
- package/cjs/storages/inMemory/SplitsCacheInMemory.js +0 -121
- package/cjs/storages/pluggable/SplitsCachePluggable.js +0 -212
- package/esm/storages/AbstractSplitsCacheAsync.js +0 -48
- package/esm/storages/AbstractSplitsCacheSync.js +0 -71
- package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +0 -191
- package/esm/storages/inMemory/SplitsCacheInMemory.js +0 -118
- package/esm/storages/pluggable/SplitsCachePluggable.js +0 -209
- package/src/storages/AbstractSplitsCacheAsync.ts +0 -63
- package/src/storages/AbstractSplitsCacheSync.ts +0 -95
- package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +0 -234
- package/src/storages/inMemory/SplitsCacheInMemory.ts +0 -130
- package/src/storages/pluggable/SplitsCachePluggable.ts +0 -230
|
@@ -2,9 +2,9 @@ import { forOwn } from '../../utils/lang';
|
|
|
2
2
|
import { mySegmentsSyncTaskFactory } from './syncTasks/mySegmentsSyncTask';
|
|
3
3
|
import { definitionsSyncTaskFactory } from './syncTasks/definitionsSyncTask';
|
|
4
4
|
import { getMatching } from '../../utils/key';
|
|
5
|
-
import {
|
|
5
|
+
import { SDK_DEFINITIONS_ARRIVED, SDK_SEGMENTS_ARRIVED } from '../../readiness/constants';
|
|
6
6
|
import { POLLING_SMART_PAUSING, POLLING_START, POLLING_STOP } from '../../logger/constants';
|
|
7
|
-
import { usesSegmentsSync } from '../../storages/
|
|
7
|
+
import { usesSegmentsSync } from '../../storages/AbstractDefinitionsCacheSync';
|
|
8
8
|
/**
|
|
9
9
|
* Expose start / stop mechanism for polling data from services.
|
|
10
10
|
* For client-side API with multiple clients.
|
|
@@ -29,7 +29,7 @@ export function pollingManagerCSFactory(params, definitionChangesFetcher) {
|
|
|
29
29
|
});
|
|
30
30
|
}
|
|
31
31
|
// smart pausing
|
|
32
|
-
readiness.
|
|
32
|
+
readiness.definitions.on(SDK_DEFINITIONS_ARRIVED, function () {
|
|
33
33
|
if (!definitionsSyncTask.isRunning())
|
|
34
34
|
return; // noop if not doing polling
|
|
35
35
|
var usingSegments = usesSegmentsSync(storage);
|
|
@@ -53,7 +53,7 @@ export function pollingManagerCSFactory(params, definitionChangesFetcher) {
|
|
|
53
53
|
if (!usesSegmentsSync(storage))
|
|
54
54
|
setTimeout(smartReady, 0);
|
|
55
55
|
else
|
|
56
|
-
readiness.
|
|
56
|
+
readiness.definitions.once(SDK_DEFINITIONS_ARRIVED, smartReady);
|
|
57
57
|
mySegmentsSyncTasks[matchingKey] = mySegmentsSyncTask;
|
|
58
58
|
return mySegmentsSyncTask;
|
|
59
59
|
}
|
|
@@ -4,11 +4,11 @@ import { POLLING_START, POLLING_STOP, LOG_PREFIX_SYNC_POLLING } from '../../logg
|
|
|
4
4
|
/**
|
|
5
5
|
* Expose start / stop mechanism for pulling data from services.
|
|
6
6
|
*/
|
|
7
|
-
export function pollingManagerSSFactory(params, definitionChangesFetcher) {
|
|
8
|
-
var
|
|
7
|
+
export function pollingManagerSSFactory(params, definitionChangesFetcher, segmentChangesFetcher) {
|
|
8
|
+
var storage = params.storage, readiness = params.readiness, settings = params.settings;
|
|
9
9
|
var log = settings.log;
|
|
10
10
|
var definitionsSyncTask = definitionsSyncTaskFactory(definitionChangesFetcher, storage, readiness, settings);
|
|
11
|
-
var segmentsSyncTask = segmentsSyncTaskFactory(
|
|
11
|
+
var segmentsSyncTask = segmentsSyncTaskFactory(segmentChangesFetcher, storage, readiness, settings);
|
|
12
12
|
return {
|
|
13
13
|
definitionsSyncTask: definitionsSyncTask,
|
|
14
14
|
segmentsSyncTask: segmentsSyncTask,
|
|
@@ -4,5 +4,5 @@ import { definitionChangesUpdaterFactory } from '../updaters/definitionChangesUp
|
|
|
4
4
|
* Creates a sync task that periodically executes a `definitionChangesUpdater` task
|
|
5
5
|
*/
|
|
6
6
|
export function definitionsSyncTaskFactory(definitionChangesFetcher, storage, readiness, settings, isClientSide) {
|
|
7
|
-
return syncTaskFactory(settings.log, definitionChangesUpdaterFactory(settings.log, definitionChangesFetcher, storage, settings.sync.__splitFiltersValidation, readiness.
|
|
7
|
+
return syncTaskFactory(settings.log, definitionChangesUpdaterFactory(settings.log, definitionChangesFetcher, storage, settings.sync.__splitFiltersValidation, readiness.definitions, settings.startup.requestTimeoutBeforeReady, settings.startup.retriesOnFailureBeforeReady, isClientSide), settings.scheduler.featuresRefreshRate, 'definitionChangesUpdater');
|
|
8
8
|
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { syncTaskFactory } from '../../syncTask';
|
|
2
|
-
import { segmentChangesFetcherFactory } from '../fetchers/segmentChangesFetcher';
|
|
3
2
|
import { segmentChangesUpdaterFactory } from '../updaters/segmentChangesUpdater';
|
|
4
3
|
/**
|
|
5
4
|
* Creates a sync task that periodically executes a `segmentChangesUpdater` task
|
|
6
5
|
*/
|
|
7
|
-
export function segmentsSyncTaskFactory(
|
|
8
|
-
return syncTaskFactory(settings.log, segmentChangesUpdaterFactory(settings.log,
|
|
6
|
+
export function segmentsSyncTaskFactory(segmentChangesFetcher, storage, readiness, settings) {
|
|
7
|
+
return syncTaskFactory(settings.log, segmentChangesUpdaterFactory(settings.log, segmentChangesFetcher, storage.segments, readiness, settings.startup.requestTimeoutBeforeReady, settings.startup.retriesOnFailureBeforeReady), settings.scheduler.segmentsRefreshRate, 'segmentChangesUpdater');
|
|
9
8
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { timeout } from '../../../utils/promise/timeout';
|
|
2
|
-
import {
|
|
2
|
+
import { SDK_DEFINITIONS_ARRIVED, FLAGS_UPDATE, SEGMENTS_UPDATE, CONFIGS_UPDATE } from '../../../readiness/constants';
|
|
3
3
|
import { SYNC_FETCH, SYNC_UPDATE, SYNC_FETCH_FAILS, SYNC_FETCH_RETRY } from '../../../logger/constants';
|
|
4
4
|
import { startsWith } from '../../../utils/lang';
|
|
5
5
|
import { IN_RULE_BASED_SEGMENT, IN_SEGMENT, RULE_BASED_SEGMENT, STANDARD_SEGMENT } from '../../../utils/constants';
|
|
@@ -101,10 +101,10 @@ function convertInstantUpdateToDefinitionChanges(instantUpdate) {
|
|
|
101
101
|
* @param requestTimeoutBeforeReady - How long the updater will wait for the request to timeout. Default 0, i.e., never timeout.
|
|
102
102
|
* @param retriesOnFailureBeforeReady - How many retries on `/splitChanges` or `/configs` we the updater do in case of failure or timeout. Default 0, i.e., no retries.
|
|
103
103
|
*/
|
|
104
|
-
export function definitionChangesUpdaterFactory(log, definitionChangesFetcher, storage, splitFiltersValidation,
|
|
104
|
+
export function definitionChangesUpdaterFactory(log, definitionChangesFetcher, storage, splitFiltersValidation, definitionsEventEmitter, requestTimeoutBeforeReady, retriesOnFailureBeforeReady, isClientSide) {
|
|
105
105
|
if (requestTimeoutBeforeReady === void 0) { requestTimeoutBeforeReady = 0; }
|
|
106
106
|
if (retriesOnFailureBeforeReady === void 0) { retriesOnFailureBeforeReady = 0; }
|
|
107
|
-
var
|
|
107
|
+
var definitions = storage.definitions, rbSegments = storage.rbSegments, segments = storage.segments;
|
|
108
108
|
var startingUp = true;
|
|
109
109
|
/** timeout decorator for `definitionChangesFetcher` promise */
|
|
110
110
|
function _promiseDecorator(promise) {
|
|
@@ -146,7 +146,7 @@ export function definitionChangesUpdaterFactory(log, definitionChangesFetcher, s
|
|
|
146
146
|
var _a = computeMutation(definitionChanges.d, usedSegments, splitFiltersValidation), added = _a.added, removed = _a.removed, names = _a.names;
|
|
147
147
|
updatedDefinitions = names;
|
|
148
148
|
log.debug(SYNC_UPDATE, [definitionChangesFetcher.type, added.length, removed.length]);
|
|
149
|
-
ffUpdate =
|
|
149
|
+
ffUpdate = definitions.update(added, removed, definitionChanges.d.till);
|
|
150
150
|
}
|
|
151
151
|
var rbsUpdate = false;
|
|
152
152
|
if (definitionChanges.rbs) {
|
|
@@ -162,9 +162,9 @@ export function definitionChangesUpdaterFactory(log, definitionChangesFetcher, s
|
|
|
162
162
|
if (storage.save)
|
|
163
163
|
storage.save();
|
|
164
164
|
startingUp = false;
|
|
165
|
-
if (
|
|
166
|
-
// To emit
|
|
167
|
-
return Promise.resolve(!
|
|
165
|
+
if (definitionsEventEmitter) {
|
|
166
|
+
// To emit SDK_DEFINITIONS_ARRIVED for server-side SDK, we must check that all registered segments have been fetched
|
|
167
|
+
return Promise.resolve(!definitionsEventEmitter.definitionsArrived || ((ffChanged || rbsChanged) && (isClientSide || checkAllSegmentsExist(segments))))
|
|
168
168
|
.catch(function () { return false; } /** noop. just to handle a possible `checkAllSegmentsExist` rejection, before emitting SDK event */)
|
|
169
169
|
.then(function (emitSplitsArrivedEvent) {
|
|
170
170
|
// emit SDK events
|
|
@@ -173,7 +173,7 @@ export function definitionChangesUpdaterFactory(log, definitionChangesFetcher, s
|
|
|
173
173
|
type: updatedDefinitions.length > 0 ? definitionChangesFetcher.type === 'configs' ? CONFIGS_UPDATE : FLAGS_UPDATE : SEGMENTS_UPDATE,
|
|
174
174
|
names: updatedDefinitions.length > 0 ? updatedDefinitions : []
|
|
175
175
|
};
|
|
176
|
-
|
|
176
|
+
definitionsEventEmitter.emit(SDK_DEFINITIONS_ARRIVED, metadata);
|
|
177
177
|
}
|
|
178
178
|
return true;
|
|
179
179
|
});
|
|
@@ -195,6 +195,6 @@ export function definitionChangesUpdaterFactory(log, definitionChangesFetcher, s
|
|
|
195
195
|
});
|
|
196
196
|
}
|
|
197
197
|
// `getChangeNumber` never rejects or throws error
|
|
198
|
-
return Promise.all([
|
|
198
|
+
return Promise.all([definitions.getChangeNumber(), rbSegments.getChangeNumber()]).then(_definitionChangesUpdater);
|
|
199
199
|
};
|
|
200
200
|
}
|
|
@@ -2,7 +2,7 @@ import { timeout } from '../../../utils/promise/timeout';
|
|
|
2
2
|
import { SDK_SEGMENTS_ARRIVED, SEGMENTS_UPDATE } from '../../../readiness/constants';
|
|
3
3
|
import { SYNC_FETCH_RETRY } from '../../../logger/constants';
|
|
4
4
|
import { MEMBERSHIPS_LS_UPDATE } from '../../streaming/constants';
|
|
5
|
-
import { usesSegmentsSync } from '../../../storages/
|
|
5
|
+
import { usesSegmentsSync } from '../../../storages/AbstractDefinitionsCacheSync';
|
|
6
6
|
/**
|
|
7
7
|
* factory of MySegments updater, a task that:
|
|
8
8
|
* - fetches mySegments using `mySegmentsFetcher`
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CONNECTION_ESTABLISHED, DISABLED, ENABLED, OCCUPANCY_PRI, OCCUPANCY_SEC, PAUSED, STREAMING_STATUS } from '../../../utils/constants';
|
|
2
|
-
import { ControlType, PUSH_SUBSYSTEM_UP,
|
|
2
|
+
import { ControlType, PUSH_SUBSYSTEM_UP, PUSH_NON_RETRYABLE_ERROR, PUSH_SUBSYSTEM_DOWN } from '../constants';
|
|
3
3
|
var CONTROL_CHANNEL_REGEXS = [/control_pri$/, /control_sec$/];
|
|
4
4
|
var STREAMING_EVENT_TYPES = [OCCUPANCY_PRI, OCCUPANCY_SEC];
|
|
5
5
|
/**
|
|
@@ -70,7 +70,7 @@ export function notificationKeeperFactory(pushEmitter, telemetryTracker) {
|
|
|
70
70
|
c.cTime = timestamp;
|
|
71
71
|
if (controlType === ControlType.STREAMING_DISABLED) {
|
|
72
72
|
telemetryTracker.streamingEvent(STREAMING_STATUS, DISABLED);
|
|
73
|
-
pushEmitter.emit(
|
|
73
|
+
pushEmitter.emit(PUSH_NON_RETRYABLE_ERROR);
|
|
74
74
|
}
|
|
75
75
|
else if (hasPublishers) {
|
|
76
76
|
if (controlType === ControlType.STREAMING_PAUSED && hasResumed) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { errorParser, messageParser } from './NotificationParser';
|
|
2
2
|
import { notificationKeeperFactory } from './NotificationKeeper';
|
|
3
|
-
import { PUSH_RETRYABLE_ERROR,
|
|
3
|
+
import { PUSH_RETRYABLE_ERROR, PUSH_NON_RETRYABLE_ERROR, OCCUPANCY, CONTROL, SEGMENT_UPDATE, SPLIT_KILL, SPLIT_UPDATE, MEMBERSHIPS_MS_UPDATE, MEMBERSHIPS_LS_UPDATE, RB_SEGMENT_UPDATE } from '../constants';
|
|
4
4
|
import { STREAMING_PARSING_ERROR_FAILS, ERROR_STREAMING_SSE, STREAMING_PARSING_MESSAGE_FAILS, STREAMING_NEW_MESSAGE } from '../../../logger/constants';
|
|
5
5
|
import { ABLY_ERROR, NON_REQUESTED, SSE_CONNECTION_ERROR } from '../../../utils/constants';
|
|
6
6
|
/**
|
|
@@ -48,7 +48,7 @@ export function SSEHandlerFactory(log, pushEmitter, telemetryTracker) {
|
|
|
48
48
|
pushEmitter.emit(PUSH_RETRYABLE_ERROR);
|
|
49
49
|
}
|
|
50
50
|
else {
|
|
51
|
-
pushEmitter.emit(
|
|
51
|
+
pushEmitter.emit(PUSH_NON_RETRYABLE_ERROR);
|
|
52
52
|
}
|
|
53
53
|
},
|
|
54
54
|
/* NotificationProcessor */
|
package/esm/sync/streaming/UpdateWorkers/{SplitsUpdateWorker.js → DefinitionsUpdateWorker.js}
RENAMED
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
import { STREAMING_PARSING_SPLIT_UPDATE } from '../../../logger/constants';
|
|
2
|
-
import {
|
|
2
|
+
import { SDK_DEFINITIONS_ARRIVED } from '../../../readiness/constants';
|
|
3
3
|
import { Backoff } from '../../../utils/Backoff';
|
|
4
4
|
import { SPLITS } from '../../../utils/constants';
|
|
5
5
|
import { RB_SEGMENT_UPDATE } from '../constants';
|
|
6
6
|
import { parseFFUpdatePayload } from '../parseUtils';
|
|
7
7
|
import { FETCH_BACKOFF_BASE, FETCH_BACKOFF_MAX_WAIT, FETCH_BACKOFF_MAX_RETRIES } from './constants';
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
9
|
+
* DefinitionsUpdateWorker factory
|
|
10
10
|
*/
|
|
11
|
-
export function
|
|
12
|
-
var ff =
|
|
13
|
-
var rbs =
|
|
14
|
-
function
|
|
11
|
+
export function DefinitionsUpdateWorker(log, storage, definitionsSyncTask, definitionsEventEmitter, telemetryTracker, segmentsSyncTask) {
|
|
12
|
+
var ff = DefinitionsUpdateWorker(storage.definitions);
|
|
13
|
+
var rbs = DefinitionsUpdateWorker(storage.rbSegments);
|
|
14
|
+
function DefinitionsUpdateWorker(cache) {
|
|
15
15
|
var maxChangeNumber = -1;
|
|
16
16
|
var handleNewEvent = false;
|
|
17
17
|
var isHandlingEvent;
|
|
18
18
|
var cdnBypass;
|
|
19
19
|
var instantUpdate;
|
|
20
|
-
var backoff = new Backoff(
|
|
21
|
-
function
|
|
20
|
+
var backoff = new Backoff(__handleDefinitionUpdateCall, FETCH_BACKOFF_BASE, FETCH_BACKOFF_MAX_WAIT);
|
|
21
|
+
function __handleDefinitionUpdateCall() {
|
|
22
22
|
isHandlingEvent = true;
|
|
23
23
|
if (maxChangeNumber > cache.getChangeNumber()) {
|
|
24
24
|
handleNewEvent = false;
|
|
@@ -27,7 +27,7 @@ export function SplitsUpdateWorker(log, storage, definitionsSyncTask, splitsEven
|
|
|
27
27
|
if (!isHandlingEvent)
|
|
28
28
|
return; // halt if `stop` has been called
|
|
29
29
|
if (handleNewEvent) {
|
|
30
|
-
|
|
30
|
+
__handleDefinitionUpdateCall();
|
|
31
31
|
}
|
|
32
32
|
else {
|
|
33
33
|
if (instantUpdate)
|
|
@@ -52,7 +52,7 @@ export function SplitsUpdateWorker(log, storage, definitionsSyncTask, splitsEven
|
|
|
52
52
|
else {
|
|
53
53
|
backoff.reset();
|
|
54
54
|
cdnBypass = true;
|
|
55
|
-
|
|
55
|
+
__handleDefinitionUpdateCall();
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
});
|
|
@@ -80,7 +80,7 @@ export function SplitsUpdateWorker(log, storage, definitionsSyncTask, splitsEven
|
|
|
80
80
|
instantUpdate = { payload: payload, changeNumber: changeNumber, type: type };
|
|
81
81
|
}
|
|
82
82
|
if (backoff.timeoutID || !isHandlingEvent)
|
|
83
|
-
|
|
83
|
+
__handleDefinitionUpdateCall();
|
|
84
84
|
backoff.reset();
|
|
85
85
|
},
|
|
86
86
|
stop: function () {
|
|
@@ -115,11 +115,11 @@ export function SplitsUpdateWorker(log, storage, definitionsSyncTask, splitsEven
|
|
|
115
115
|
* @param splitName - name of split to kill
|
|
116
116
|
* @param defaultTreatment - default treatment value
|
|
117
117
|
*/
|
|
118
|
-
|
|
118
|
+
killDefinition: function (_a) {
|
|
119
119
|
var changeNumber = _a.changeNumber, splitName = _a.splitName, defaultTreatment = _a.defaultTreatment;
|
|
120
|
-
if (storage.
|
|
120
|
+
if (storage.definitions.killLocally(splitName, defaultTreatment, changeNumber)) {
|
|
121
121
|
// trigger an SDK_UPDATE if Split was killed locally
|
|
122
|
-
|
|
122
|
+
definitionsEventEmitter.emit(SDK_DEFINITIONS_ARRIVED, true);
|
|
123
123
|
}
|
|
124
124
|
// queues the SplitChanges fetch (only if changeNumber is newer)
|
|
125
125
|
ff.put({ changeNumber: changeNumber });
|
|
@@ -5,7 +5,7 @@ export var SECONDS_BEFORE_EXPIRATION = 600;
|
|
|
5
5
|
* emitted on SSE and Authenticate non-recoverable errors, STREAMING_DISABLED control notification and authentication with pushEnabled false
|
|
6
6
|
* triggers `handleNonRetryableError` call
|
|
7
7
|
*/
|
|
8
|
-
export var
|
|
8
|
+
export var PUSH_NON_RETRYABLE_ERROR = 'PUSH_NON_RETRYABLE_ERROR';
|
|
9
9
|
/**
|
|
10
10
|
* emitted on SSE and Authenticate recoverable errors
|
|
11
11
|
* triggers `handleRetryableError` call
|
|
@@ -17,7 +17,7 @@ export var PUSH_RETRYABLE_ERROR = 'PUSH_RETRYABLE_ERROR';
|
|
|
17
17
|
*/
|
|
18
18
|
export var PUSH_SUBSYSTEM_UP = 'PUSH_SUBSYSTEM_UP';
|
|
19
19
|
/**
|
|
20
|
-
* emitted on STREAMING_PAUSED control notification, OCCUPANCY equal to 0,
|
|
20
|
+
* emitted on STREAMING_PAUSED control notification, OCCUPANCY equal to 0, PUSH_NON_RETRYABLE_ERROR and PUSH_RETRYABLE_ERROR events.
|
|
21
21
|
* triggers `startPolling` and `stopWorkers` calls
|
|
22
22
|
*/
|
|
23
23
|
export var PUSH_SUBSYSTEM_DOWN = 'PUSH_SUBSYSTEM_DOWN';
|
|
@@ -3,12 +3,12 @@ import { Backoff } from '../../utils/Backoff';
|
|
|
3
3
|
import { SSEHandlerFactory } from './SSEHandler';
|
|
4
4
|
import { MySegmentsUpdateWorker } from './UpdateWorkers/MySegmentsUpdateWorker';
|
|
5
5
|
import { SegmentsUpdateWorker } from './UpdateWorkers/SegmentsUpdateWorker';
|
|
6
|
-
import {
|
|
6
|
+
import { DefinitionsUpdateWorker } from './UpdateWorkers/DefinitionsUpdateWorker';
|
|
7
7
|
import { authenticateFactory, hashUserKey } from './AuthClient';
|
|
8
8
|
import { forOwn } from '../../utils/lang';
|
|
9
9
|
import { SSEClient } from './SSEClient';
|
|
10
10
|
import { checkIfServerSide, getMatching } from '../../utils/key';
|
|
11
|
-
import { MEMBERSHIPS_MS_UPDATE, MEMBERSHIPS_LS_UPDATE,
|
|
11
|
+
import { MEMBERSHIPS_MS_UPDATE, MEMBERSHIPS_LS_UPDATE, PUSH_NON_RETRYABLE_ERROR, PUSH_SUBSYSTEM_DOWN, SECONDS_BEFORE_EXPIRATION, SEGMENT_UPDATE, SPLIT_KILL, SPLIT_UPDATE, RB_SEGMENT_UPDATE, PUSH_RETRYABLE_ERROR, PUSH_SUBSYSTEM_UP, ControlType } from './constants';
|
|
12
12
|
import { STREAMING_FALLBACK, STREAMING_REFRESH_TOKEN, STREAMING_CONNECTING, STREAMING_DISABLED, ERROR_STREAMING_AUTH, STREAMING_DISCONNECTING, STREAMING_RECONNECT, STREAMING_PARSING_MEMBERSHIPS_UPDATE } from '../../logger/constants';
|
|
13
13
|
import { UpdateStrategy } from './SSEHandler/types';
|
|
14
14
|
import { getDelay, isInBitmap, parseBitmap, parseCompressedData } from './parseUtils';
|
|
@@ -42,8 +42,8 @@ export function pushManagerFactory(params, pollingManager) {
|
|
|
42
42
|
// init workers
|
|
43
43
|
// MySegmentsUpdateWorker (client-side) are initiated in `add` method
|
|
44
44
|
var segmentsUpdateWorker = userKey ? undefined : SegmentsUpdateWorker(log, pollingManager.segmentsSyncTask, storage.segments);
|
|
45
|
-
// For server-side we pass the segmentsSyncTask, used by
|
|
46
|
-
var
|
|
45
|
+
// For server-side we pass the segmentsSyncTask, used by DefinitionsUpdateWorker to fetch new segments
|
|
46
|
+
var definitionsUpdateWorker = DefinitionsUpdateWorker(log, storage, pollingManager.definitionsSyncTask, readiness.definitions, telemetryTracker, userKey ? undefined : pollingManager.segmentsSyncTask);
|
|
47
47
|
// [Only for client-side] map of hashes to user keys, to dispatch membership update events to the corresponding MySegmentsUpdateWorker
|
|
48
48
|
var userKeyHashes = {};
|
|
49
49
|
// [Only for client-side] map of user keys to their corresponding hash64 and MySegmentsUpdateWorkers.
|
|
@@ -51,10 +51,10 @@ export function pushManagerFactory(params, pollingManager) {
|
|
|
51
51
|
var clients = {};
|
|
52
52
|
// [Only for client-side] variable to flag that a new client was added. It is needed to reconnect streaming.
|
|
53
53
|
var connectForNewClient = false;
|
|
54
|
-
// flag that indicates if `stop/disconnectPush` was called, either by the SyncManager, when the client is destroyed, or due to a
|
|
54
|
+
// flag that indicates if `stop/disconnectPush` was called, either by the SyncManager, when the client is destroyed, or due to a PUSH_NON_RETRYABLE_ERROR error.
|
|
55
55
|
// It is used to halt the `connectPush` process if it was in progress.
|
|
56
56
|
var disconnected;
|
|
57
|
-
// flag that indicates a
|
|
57
|
+
// flag that indicates a PUSH_NON_RETRYABLE_ERROR, condition with which starting pushManager again is ignored.
|
|
58
58
|
// true if STREAMING_DISABLED control event, or 'pushEnabled: false', or non-recoverable SSE or Auth errors.
|
|
59
59
|
var disabled; // `disabled` implies `disconnected === true`
|
|
60
60
|
/** PushManager functions related to initialization */
|
|
@@ -93,11 +93,11 @@ export function pushManagerFactory(params, pollingManager) {
|
|
|
93
93
|
authenticate(userKeys).then(function (authData) {
|
|
94
94
|
if (disconnected)
|
|
95
95
|
return;
|
|
96
|
-
// 'pushEnabled: false' is handled as a
|
|
96
|
+
// 'pushEnabled: false' is handled as a PUSH_NON_RETRYABLE_ERROR instead of PUSH_SUBSYSTEM_DOWN, in order to
|
|
97
97
|
// close the sseClient in case the org has been bloqued while the instance was connected to streaming
|
|
98
98
|
if (!authData.pushEnabled) {
|
|
99
99
|
log.info(STREAMING_DISABLED);
|
|
100
|
-
pushEmitter.emit(
|
|
100
|
+
pushEmitter.emit(PUSH_NON_RETRYABLE_ERROR);
|
|
101
101
|
return;
|
|
102
102
|
}
|
|
103
103
|
// [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
|
|
@@ -112,7 +112,7 @@ export function pushManagerFactory(params, pollingManager) {
|
|
|
112
112
|
// Handle 4XX HTTP errors: 401 (invalid SDK Key) or 400 (using incorrect SDK Key, i.e., client-side SDK Key on server-side)
|
|
113
113
|
if (error.statusCode >= 400 && error.statusCode < 500) {
|
|
114
114
|
telemetryTracker.streamingEvent(AUTH_REJECTION);
|
|
115
|
-
pushEmitter.emit(
|
|
115
|
+
pushEmitter.emit(PUSH_NON_RETRYABLE_ERROR);
|
|
116
116
|
return;
|
|
117
117
|
}
|
|
118
118
|
// Handle other HTTP and network errors as recoverable errors
|
|
@@ -136,7 +136,7 @@ export function pushManagerFactory(params, pollingManager) {
|
|
|
136
136
|
}
|
|
137
137
|
// cancel scheduled fetch retries of Splits, Segments, and MySegments Update Workers
|
|
138
138
|
function stopWorkers() {
|
|
139
|
-
|
|
139
|
+
definitionsUpdateWorker.stop();
|
|
140
140
|
if (userKey)
|
|
141
141
|
forOwn(clients, function (_a) {
|
|
142
142
|
var worker = _a.worker;
|
|
@@ -152,7 +152,7 @@ export function pushManagerFactory(params, pollingManager) {
|
|
|
152
152
|
connectPushRetryBackoff.reset();
|
|
153
153
|
});
|
|
154
154
|
/** Fallback to polling without retry due to: STREAMING_DISABLED control event, or 'pushEnabled: false', or non-recoverable SSE and Authentication errors */
|
|
155
|
-
pushEmitter.on(
|
|
155
|
+
pushEmitter.on(PUSH_NON_RETRYABLE_ERROR, function handleNonRetryableError() {
|
|
156
156
|
disabled = true;
|
|
157
157
|
// Note: `stopWorkers` is been called twice, but it is not harmful
|
|
158
158
|
disconnectPush();
|
|
@@ -178,9 +178,9 @@ export function pushManagerFactory(params, pollingManager) {
|
|
|
178
178
|
connectPush();
|
|
179
179
|
});
|
|
180
180
|
/** Functions related to synchronization (Queues and Workers in the spec) */
|
|
181
|
-
pushEmitter.on(SPLIT_KILL,
|
|
182
|
-
pushEmitter.on(SPLIT_UPDATE,
|
|
183
|
-
pushEmitter.on(RB_SEGMENT_UPDATE,
|
|
181
|
+
pushEmitter.on(SPLIT_KILL, definitionsUpdateWorker.killDefinition);
|
|
182
|
+
pushEmitter.on(SPLIT_UPDATE, definitionsUpdateWorker.put);
|
|
183
|
+
pushEmitter.on(RB_SEGMENT_UPDATE, definitionsUpdateWorker.put);
|
|
184
184
|
function handleMySegmentsUpdate(parsedData) {
|
|
185
185
|
switch (parsedData.u) {
|
|
186
186
|
case UpdateStrategy.BoundedFetchRequest: {
|
|
@@ -102,13 +102,12 @@ export function telemetrySubmitterFactory(params) {
|
|
|
102
102
|
var telemetry = params.storage.telemetry, now = params.platform.now;
|
|
103
103
|
if (!telemetry || !now)
|
|
104
104
|
return; // No submitter created if telemetry cache is not defined
|
|
105
|
-
var settings = params.settings, _a = params.settings, log = _a.log, telemetryRefreshRate = _a.scheduler.telemetryRefreshRate, splitApi = params.splitApi, readiness = params.readiness
|
|
105
|
+
var settings = params.settings, _a = params.settings, log = _a.log, telemetryRefreshRate = _a.scheduler.telemetryRefreshRate, splitApi = params.splitApi, readiness = params.readiness;
|
|
106
106
|
var stopTimer = timer(now);
|
|
107
107
|
var submitter = firstPushWindowDecorator(submitterFactory(log, splitApi.postMetricsUsage, telemetry, telemetryRefreshRate, undefined, 0, true), telemetryRefreshRate);
|
|
108
108
|
readiness.gate.once(SDK_READY_FROM_CACHE, function () {
|
|
109
109
|
telemetry.recordTimeUntilReadyFromCache(stopTimer());
|
|
110
110
|
});
|
|
111
|
-
sdkReadinessManager.incInternalReadyCbCount();
|
|
112
111
|
readiness.gate.once(SDK_READY, function () {
|
|
113
112
|
telemetry.recordTimeUntilReady(stopTimer());
|
|
114
113
|
// Post config data when the SDK is ready and if the telemetry submitter was started
|
|
@@ -3,9 +3,10 @@ import { PUSH_SUBSYSTEM_UP, PUSH_SUBSYSTEM_DOWN } from './streaming/constants';
|
|
|
3
3
|
import { SYNC_START_POLLING, SYNC_CONTINUE_POLLING, SYNC_STOP_POLLING } from '../logger/constants';
|
|
4
4
|
import { isConsentGranted } from '../consent';
|
|
5
5
|
import { POLLING, STREAMING, SYNC_MODE_UPDATE } from '../utils/constants';
|
|
6
|
-
import {
|
|
7
|
-
import { usesSegmentsSync } from '../storages/
|
|
6
|
+
import { SDK_DEFINITIONS_CACHE_LOADED } from '../readiness/constants';
|
|
7
|
+
import { usesSegmentsSync } from '../storages/AbstractDefinitionsCacheSync';
|
|
8
8
|
import { splitChangesFetcherFactory } from './polling/fetchers/splitChangesFetcher';
|
|
9
|
+
import { segmentChangesFetcherFactory } from './polling/fetchers/segmentChangesFetcher';
|
|
9
10
|
/**
|
|
10
11
|
* Online SyncManager factory.
|
|
11
12
|
* Can be used for server-side API, and client-side API with or without multiple clients.
|
|
@@ -15,21 +16,22 @@ import { splitChangesFetcherFactory } from './polling/fetchers/splitChangesFetch
|
|
|
15
16
|
* @param pushManagerFactory - optional to build a SyncManager with or without streaming support
|
|
16
17
|
* @param definitionChangesFetcherFactory - optional to replace the default split changes fetcher
|
|
17
18
|
*/
|
|
18
|
-
export function syncManagerOnlineFactory(pollingManagerFactory, pushManagerFactory,
|
|
19
|
-
if (
|
|
19
|
+
export function syncManagerOnlineFactory(pollingManagerFactory, pushManagerFactory, definitionFetcherFactory, segmentFetcherFactory) {
|
|
20
|
+
if (definitionFetcherFactory === void 0) { definitionFetcherFactory = splitChangesFetcherFactory; }
|
|
21
|
+
if (segmentFetcherFactory === void 0) { segmentFetcherFactory = function (params) { return segmentChangesFetcherFactory(params.splitApi.fetchSegmentChanges); }; }
|
|
20
22
|
/**
|
|
21
23
|
* SyncManager factory for modular SDK
|
|
22
24
|
*/
|
|
23
25
|
return function (params) {
|
|
24
26
|
var settings = params.settings, _a = params.settings, log = _a.log, streamingEnabled = _a.streamingEnabled, syncEnabled = _a.sync.enabled, telemetryTracker = params.telemetryTracker, storage = params.storage, readiness = params.readiness;
|
|
25
27
|
/** Polling Manager */
|
|
26
|
-
var pollingManager = pollingManagerFactory && pollingManagerFactory(params,
|
|
28
|
+
var pollingManager = pollingManagerFactory && pollingManagerFactory(params, definitionFetcherFactory(params), segmentFetcherFactory(params));
|
|
27
29
|
/** Push Manager */
|
|
28
30
|
var pushManager = syncEnabled && streamingEnabled && pollingManager && pushManagerFactory ?
|
|
29
31
|
pushManagerFactory(params, pollingManager) :
|
|
30
32
|
undefined;
|
|
31
33
|
/** Submitter Manager */
|
|
32
|
-
// It is not
|
|
34
|
+
// It is not injected as push and polling managers, because at the moment it is required
|
|
33
35
|
var submitterManager = submitterManagerFactory(params);
|
|
34
36
|
/** Sync Manager logic */
|
|
35
37
|
function startPolling() {
|
|
@@ -77,7 +79,7 @@ export function syncManagerOnlineFactory(pollingManagerFactory, pushManagerFacto
|
|
|
77
79
|
if (startFirstTime) {
|
|
78
80
|
// Emits SDK_READY_FROM_CACHE
|
|
79
81
|
if (!cacheMetadata.initialCacheLoad) {
|
|
80
|
-
readiness.
|
|
82
|
+
readiness.definitions.emit(SDK_DEFINITIONS_CACHE_LOADED, cacheMetadata);
|
|
81
83
|
}
|
|
82
84
|
}
|
|
83
85
|
// start syncing splits and segments
|
package/esm/utils/Backoff.js
CHANGED
|
@@ -24,6 +24,26 @@ var Backoff = /** @class */ (function () {
|
|
|
24
24
|
this.attempts++;
|
|
25
25
|
return delayInMillis;
|
|
26
26
|
};
|
|
27
|
+
/**
|
|
28
|
+
* Schedule a delayed call to `cb`
|
|
29
|
+
* @returns a promise that resolves/rejects with the result of the `cb` function, which must return a promise.
|
|
30
|
+
*/
|
|
31
|
+
Backoff.prototype.scheduleCallAsync = function () {
|
|
32
|
+
var _this = this;
|
|
33
|
+
var delayInMillis = Math.min(this.baseMillis * Math.pow(2, this.attempts), this.maxMillis);
|
|
34
|
+
if (this.timeoutID)
|
|
35
|
+
clearTimeout(this.timeoutID);
|
|
36
|
+
this.attempts++;
|
|
37
|
+
return new Promise(function (resolve, reject) {
|
|
38
|
+
_this.timeoutID = setTimeout(function () {
|
|
39
|
+
_this.timeoutID = undefined;
|
|
40
|
+
_this.cb().then(resolve, reject);
|
|
41
|
+
}, delayInMillis);
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Reset the backoff attempts
|
|
46
|
+
*/
|
|
27
47
|
Backoff.prototype.reset = function () {
|
|
28
48
|
this.attempts = 0;
|
|
29
49
|
if (this.timeoutID) {
|
package/esm/utils/lang/sets.js
CHANGED
|
@@ -10,8 +10,8 @@ export function setToArray(set) {
|
|
|
10
10
|
export function returnSetsUnion(set, set2) {
|
|
11
11
|
return new Set(setToArray(set).concat(setToArray(set2)));
|
|
12
12
|
}
|
|
13
|
-
export function returnDifference(
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
return
|
|
13
|
+
export function returnDifference(list1, list2) {
|
|
14
|
+
list1 = list1 || [];
|
|
15
|
+
list2 = list2 || [];
|
|
16
|
+
return list1.filter(function (item) { return list2.indexOf(item) === -1; });
|
|
17
17
|
}
|
|
@@ -52,6 +52,8 @@ export var base = {
|
|
|
52
52
|
streaming: 'https://streaming.split.io',
|
|
53
53
|
// Telemetry Server
|
|
54
54
|
telemetry: 'https://telemetry.split.io/api',
|
|
55
|
+
// Configs Server
|
|
56
|
+
configs: 'https://configs.split.io/api',
|
|
55
57
|
},
|
|
56
58
|
// Defines which kind of storage we should instantiate.
|
|
57
59
|
storage: undefined,
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
var telemetryEndpointMatcher = /^\/v1\/metrics\/(config|usage)/;
|
|
1
|
+
var telemetryEndpointMatcher = /^\/v1\/(metrics|keys)\/(config|usage|ss|cs)/;
|
|
2
2
|
var eventsEndpointMatcher = /^\/(testImpressions|metrics|events)/;
|
|
3
|
-
var authEndpointMatcher = /^\/v2\/auth/;
|
|
3
|
+
var authEndpointMatcher = /^\/(v2|v3)\/auth/;
|
|
4
4
|
var streamingEndpointMatcher = /^\/(sse|event-stream)/;
|
|
5
|
+
var configsEndpointMatcher = /^\/v1\/(configs|segmentChanges)/;
|
|
5
6
|
/**
|
|
6
7
|
* Get URL based on a given target (path).
|
|
7
8
|
* ATM, it is only used for testing purposes.
|
|
@@ -23,5 +24,8 @@ export function url(settings, target) {
|
|
|
23
24
|
if (streamingEndpointMatcher.test(target)) {
|
|
24
25
|
return "".concat(settings.urls.streaming).concat(target);
|
|
25
26
|
}
|
|
27
|
+
if (configsEndpointMatcher.test(target)) {
|
|
28
|
+
return "".concat(settings.urls.configs).concat(target);
|
|
29
|
+
}
|
|
26
30
|
return "".concat(settings.urls.sdk).concat(target);
|
|
27
31
|
}
|
package/package.json
CHANGED
package/src/dtos/types.ts
CHANGED
|
@@ -217,7 +217,7 @@ export interface IRBSegment extends TargetingEntity {
|
|
|
217
217
|
|
|
218
218
|
export interface IDefinition extends TargetingEntity {
|
|
219
219
|
trafficTypeName: string;
|
|
220
|
-
sets?: string[];
|
|
220
|
+
sets?: string[] | null;
|
|
221
221
|
impressionsDisabled?: boolean;
|
|
222
222
|
prerequisites?: null | {
|
|
223
223
|
n: string,
|
|
@@ -230,7 +230,7 @@ export interface IDefinition extends TargetingEntity {
|
|
|
230
230
|
trafficAllocationSeed?: number;
|
|
231
231
|
configurations?: {
|
|
232
232
|
[treatmentName: string]: string | SplitIO.JsonObject
|
|
233
|
-
};
|
|
233
|
+
} | null;
|
|
234
234
|
}
|
|
235
235
|
|
|
236
236
|
/** Interface of the parsed JSON response of `/splitChanges` */
|
package/src/evaluator/index.ts
CHANGED
|
@@ -41,9 +41,9 @@ export function evaluateFeature(
|
|
|
41
41
|
let definition;
|
|
42
42
|
|
|
43
43
|
try {
|
|
44
|
-
definition = storage.
|
|
44
|
+
definition = storage.definitions.get(definitionName);
|
|
45
45
|
} catch (e) {
|
|
46
|
-
// Exception on sync
|
|
46
|
+
// Exception on sync storage. Not possible ATM with InMemory and InLocal storages.
|
|
47
47
|
return EVALUATION_EXCEPTION;
|
|
48
48
|
}
|
|
49
49
|
|
|
@@ -56,7 +56,7 @@ export function evaluateFeature(
|
|
|
56
56
|
storage,
|
|
57
57
|
options,
|
|
58
58
|
)).catch(
|
|
59
|
-
// Exception on async
|
|
59
|
+
// Exception on async storage. For example, when the storage is redis or
|
|
60
60
|
// pluggable and there is a connection issue and we can't retrieve the split to be evaluated
|
|
61
61
|
() => EVALUATION_EXCEPTION
|
|
62
62
|
);
|
|
@@ -83,16 +83,16 @@ export function evaluateFeatures(
|
|
|
83
83
|
let definitions;
|
|
84
84
|
|
|
85
85
|
try {
|
|
86
|
-
definitions = storage.
|
|
86
|
+
definitions = storage.definitions.getMany(definitionNames);
|
|
87
87
|
} catch (e) {
|
|
88
|
-
// Exception on sync
|
|
88
|
+
// Exception on sync storage. Not possible ATM with InMemory and InLocal storages.
|
|
89
89
|
return treatmentsException(definitionNames);
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
return thenable(definitions) ?
|
|
93
93
|
definitions.then(definitions => getEvaluations(log, key, definitionNames, definitions, attributes, storage, options))
|
|
94
94
|
.catch(() => {
|
|
95
|
-
// Exception on async
|
|
95
|
+
// Exception on async storage. For example, when the storage is redis or
|
|
96
96
|
// pluggable and there is a connection issue and we can't retrieve the split to be evaluated
|
|
97
97
|
return treatmentsException(definitionNames);
|
|
98
98
|
}) :
|
|
@@ -128,7 +128,7 @@ export function evaluateFeaturesByFlagSets(
|
|
|
128
128
|
|
|
129
129
|
// get features by flag sets
|
|
130
130
|
try {
|
|
131
|
-
storedFlagNames = storage.
|
|
131
|
+
storedFlagNames = storage.definitions.getNamesBySets(flagSets);
|
|
132
132
|
} catch (e) {
|
|
133
133
|
// return empty evaluations
|
|
134
134
|
return {};
|
|
@@ -156,7 +156,7 @@ function getEvaluation(
|
|
|
156
156
|
const split = engineParser(log, definition, storage);
|
|
157
157
|
const evaluation = split.getTreatment(key, attributes, evaluateFeature);
|
|
158
158
|
|
|
159
|
-
// If the storage is async and the evaluated
|
|
159
|
+
// If the storage is async and the evaluated definition uses segments or dependencies, evaluation is thenable
|
|
160
160
|
if (thenable(evaluation)) {
|
|
161
161
|
return evaluation.then(result => {
|
|
162
162
|
result.changeNumber = definition.changeNumber;
|
|
@@ -183,7 +183,7 @@ function getEvaluations(
|
|
|
183
183
|
log: ILogger,
|
|
184
184
|
key: SplitIO.SplitKey,
|
|
185
185
|
definitionNames: string[],
|
|
186
|
-
|
|
186
|
+
definitions: Record<string, IDefinition | null>,
|
|
187
187
|
attributes: SplitIO.Attributes | undefined,
|
|
188
188
|
storage: IStorageSync | IStorageAsync,
|
|
189
189
|
options?: SplitIO.EvaluationOptions,
|
|
@@ -194,7 +194,7 @@ function getEvaluations(
|
|
|
194
194
|
const evaluation = getEvaluation(
|
|
195
195
|
log,
|
|
196
196
|
key,
|
|
197
|
-
|
|
197
|
+
definitions[definitionName],
|
|
198
198
|
attributes,
|
|
199
199
|
storage,
|
|
200
200
|
options
|
|
@@ -218,7 +218,7 @@ export function evaluateDefaultTreatment(
|
|
|
218
218
|
let definition;
|
|
219
219
|
|
|
220
220
|
try {
|
|
221
|
-
definition = storage.
|
|
221
|
+
definition = storage.definitions.get(definitionName);
|
|
222
222
|
} catch (e) {
|
|
223
223
|
return EVALUATION_EXCEPTION;
|
|
224
224
|
}
|
package/src/logger/constants.ts
CHANGED
|
@@ -56,7 +56,6 @@ export const SUBMITTERS_PUSH_PAGE_HIDDEN = 125;
|
|
|
56
56
|
|
|
57
57
|
export const ENGINE_VALUE_INVALID = 200;
|
|
58
58
|
export const ENGINE_VALUE_NO_ATTRIBUTES = 201;
|
|
59
|
-
export const CLIENT_NO_LISTENER = 202;
|
|
60
59
|
export const CLIENT_NOT_READY_FROM_CACHE = 203;
|
|
61
60
|
export const SYNC_FETCH_RETRY = 204;
|
|
62
61
|
export const SYNC_FETCH_FAILS = 205;
|
|
@@ -123,6 +122,7 @@ export const LOG_PREFIX_ENGINE_COMBINER = LOG_PREFIX_ENGINE + ':combiner: ';
|
|
|
123
122
|
export const LOG_PREFIX_ENGINE_MATCHER = LOG_PREFIX_ENGINE + ':matcher: ';
|
|
124
123
|
export const LOG_PREFIX_ENGINE_VALUE = LOG_PREFIX_ENGINE + ':value: ';
|
|
125
124
|
export const LOG_PREFIX_SYNC = 'sync: ';
|
|
125
|
+
export const LOG_PREFIX_SYNC_AUTH = 'sync:auth: ';
|
|
126
126
|
export const LOG_PREFIX_SYNC_MANAGER = 'sync:sync-manager: ';
|
|
127
127
|
export const LOG_PREFIX_SYNC_OFFLINE = 'sync:offline: ';
|
|
128
128
|
export const LOG_PREFIX_SYNC_STREAMING = 'sync:streaming: ';
|