@splitsoftware/splitio-commons 2.11.1-rc.2 → 3.0.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGES.txt +15 -2
- package/cjs/evaluator/condition/engineUtils.js +2 -2
- package/cjs/evaluator/fallbackConfigsCalculator/fallbackSanitizer/index.js +70 -0
- package/cjs/evaluator/fallbackConfigsCalculator/index.js +25 -0
- package/cjs/evaluator/fallbackTreatmentsCalculator/fallbackSanitizer/index.js +5 -8
- package/cjs/evaluator/fallbackTreatmentsCalculator/index.js +21 -32
- package/cjs/evaluator/index.js +67 -42
- package/cjs/evaluator/matchers/whitelist.js +1 -1
- package/cjs/integrations/pluggable.js +1 -1
- package/cjs/listeners/browser.js +4 -3
- package/cjs/listeners/node.js +4 -4
- package/cjs/logger/constants.js +14 -20
- package/cjs/logger/index.js +1 -1
- package/cjs/logger/messages/debug.js +6 -7
- package/cjs/logger/messages/error.js +4 -4
- package/cjs/logger/messages/info.js +2 -4
- package/cjs/logger/messages/warn.js +9 -9
- package/cjs/platform/browser.js +15 -0
- package/cjs/platform/getEventSource/browser.js +8 -0
- package/cjs/platform/getEventSource/eventsource.js +480 -0
- package/cjs/platform/getEventSource/node.js +26 -0
- package/cjs/platform/getFetch/browser.js +9 -0
- package/cjs/platform/getFetch/node.js +27 -0
- package/cjs/platform/getOptions/node.js +25 -0
- package/cjs/platform/node.js +17 -0
- package/cjs/readiness/constants.js +2 -1
- package/cjs/sdkClient/client.js +9 -35
- package/cjs/sdkClient/clientAttributesDecoration.js +3 -3
- package/cjs/sdkClient/clientInputValidation.js +38 -81
- package/cjs/sdkClient/identity.js +1 -1
- package/cjs/sdkClient/sdkClient.js +4 -49
- package/cjs/sdkClient/sdkLifecycle.js +70 -0
- package/cjs/sdkClient/trackMethod.js +56 -0
- package/cjs/sdkFactory/index.js +8 -45
- package/cjs/sdkManager/index.js +3 -3
- package/cjs/services/splitApi.js +18 -13
- package/cjs/services/splitHttpClient.js +1 -1
- package/cjs/storages/AbstractSplitsCacheAsync.js +1 -1
- package/cjs/storages/AbstractSplitsCacheSync.js +1 -1
- package/cjs/storages/KeyBuilder.js +12 -12
- package/cjs/storages/KeyBuilderCS.js +13 -13
- package/cjs/storages/KeyBuilderSS.js +15 -15
- package/cjs/storages/getRolloutPlan.js +1 -1
- package/cjs/storages/inLocalStorage/MySegmentsCacheInLocal.js +1 -1
- package/cjs/storages/inLocalStorage/RBSegmentsCacheInLocal.js +1 -1
- package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +1 -1
- package/cjs/storages/inMemory/ImpressionCountsCacheInMemory.js +1 -1
- package/cjs/storages/inMemory/MySegmentsCacheInMemory.js +1 -1
- package/cjs/storages/inMemory/RBSegmentsCacheInMemory.js +1 -1
- package/cjs/storages/inMemory/SplitsCacheInMemory.js +1 -1
- package/cjs/storages/inMemory/TelemetryCacheInMemory.js +2 -2
- package/cjs/storages/inRedis/EventsCacheInRedis.js +1 -1
- package/cjs/storages/inRedis/ImpressionCountsCacheInRedis.js +5 -5
- package/cjs/storages/inRedis/ImpressionsCacheInRedis.js +1 -1
- package/cjs/storages/inRedis/RBSegmentsCacheInRedis.js +1 -1
- package/cjs/storages/inRedis/RedisAdapter.js +8 -8
- package/cjs/storages/inRedis/SplitsCacheInRedis.js +6 -6
- package/cjs/storages/inRedis/TelemetryCacheInRedis.js +7 -7
- package/cjs/storages/inRedis/UniqueKeysCacheInRedis.js +3 -3
- package/cjs/storages/pluggable/EventsCachePluggable.js +1 -1
- package/cjs/storages/pluggable/ImpressionCountsCachePluggable.js +6 -6
- package/cjs/storages/pluggable/RBSegmentsCachePluggable.js +1 -1
- package/cjs/storages/pluggable/SplitsCachePluggable.js +4 -4
- package/cjs/storages/pluggable/TelemetryCachePluggable.js +7 -7
- package/cjs/storages/pluggable/UniqueKeysCachePluggable.js +2 -2
- package/cjs/storages/pluggable/index.js +3 -3
- package/cjs/storages/pluggable/wrapperAdapter.js +1 -1
- package/cjs/storages/setRolloutPlan.js +1 -1
- package/cjs/storages/utils.js +6 -6
- package/cjs/sync/offline/splitsParser/parseCondition.js +1 -1
- package/cjs/sync/polling/fetchers/segmentChangesFetcher.js +1 -1
- package/cjs/sync/polling/fetchers/splitChangesFetcher.js +23 -14
- package/cjs/sync/polling/pollingManagerCS.js +11 -11
- package/cjs/sync/polling/pollingManagerSS.js +13 -13
- package/cjs/sync/polling/syncTasks/definitionsSyncTask.js +12 -0
- package/cjs/sync/polling/updaters/{splitChangesUpdater.js → definitionChangesUpdater.js} +67 -59
- package/cjs/sync/polling/updaters/mySegmentsUpdater.js +1 -1
- package/cjs/sync/polling/updaters/segmentChangesUpdater.js +6 -6
- package/cjs/sync/streaming/SSEClient/index.js +2 -2
- package/cjs/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +2 -2
- package/cjs/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.js +2 -2
- package/cjs/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +4 -4
- package/cjs/sync/streaming/parseUtils.js +12 -12
- package/cjs/sync/streaming/pushManager.js +2 -2
- package/cjs/sync/submitters/impressionsSubmitter.js +6 -6
- package/cjs/sync/submitters/submitter.js +1 -1
- package/cjs/sync/syncManagerOnline.js +5 -2
- package/cjs/trackers/eventTracker.js +10 -12
- package/cjs/trackers/impressionObserver/buildKey.js +1 -1
- package/cjs/trackers/impressionsTracker.js +37 -20
- package/cjs/trackers/uniqueKeysTracker.js +1 -1
- package/cjs/utils/EventEmitter.js +391 -0
- package/cjs/utils/filter/bloomFilter.js +37 -0
- package/cjs/utils/inputValidation/apiKey.js +1 -1
- package/cjs/utils/inputValidation/attribute.js +2 -2
- package/cjs/utils/inputValidation/{split.js → definition.js} +10 -10
- package/cjs/utils/inputValidation/{splitExistence.js → definitionExistence.js} +6 -6
- package/cjs/utils/inputValidation/definitions.js +25 -0
- package/cjs/utils/inputValidation/eventProperties.js +1 -1
- package/cjs/utils/inputValidation/index.js +7 -7
- package/cjs/utils/inputValidation/isOperational.js +4 -4
- package/cjs/utils/inputValidation/target.js +22 -0
- package/cjs/utils/labels/index.js +3 -3
- package/cjs/utils/lang/index.js +1 -1
- package/cjs/utils/promise/timeout.js +1 -1
- package/cjs/utils/settingsValidation/splitFilters.js +4 -4
- package/cjs/utils/settingsValidation/url.js +5 -5
- package/esm/evaluator/condition/engineUtils.js +2 -2
- package/esm/evaluator/fallbackConfigsCalculator/fallbackSanitizer/index.js +64 -0
- package/esm/evaluator/fallbackConfigsCalculator/index.js +21 -0
- package/esm/evaluator/fallbackTreatmentsCalculator/fallbackSanitizer/index.js +5 -8
- package/esm/evaluator/fallbackTreatmentsCalculator/index.js +21 -33
- package/esm/evaluator/index.js +66 -42
- package/esm/evaluator/matchers/whitelist.js +1 -1
- package/esm/integrations/pluggable.js +1 -1
- package/esm/listeners/browser.js +4 -3
- package/esm/listeners/node.js +4 -4
- package/esm/logger/constants.js +11 -17
- package/esm/logger/index.js +1 -1
- package/esm/logger/messages/debug.js +5 -6
- package/esm/logger/messages/error.js +3 -3
- package/esm/logger/messages/info.js +1 -3
- package/esm/logger/messages/warn.js +8 -8
- package/esm/platform/browser.js +12 -0
- package/esm/platform/getEventSource/browser.js +4 -0
- package/esm/platform/getEventSource/eventsource.js +480 -0
- package/esm/platform/getEventSource/node.js +20 -0
- package/esm/platform/getFetch/browser.js +5 -0
- package/esm/platform/getFetch/node.js +22 -0
- package/esm/platform/getOptions/node.js +20 -0
- package/esm/platform/node.js +14 -0
- package/esm/readiness/constants.js +1 -0
- package/esm/sdkClient/client.js +10 -37
- package/esm/sdkClient/clientAttributesDecoration.js +3 -3
- package/esm/sdkClient/clientInputValidation.js +40 -83
- package/esm/sdkClient/identity.js +1 -1
- package/esm/sdkClient/sdkClient.js +4 -49
- package/esm/sdkClient/sdkLifecycle.js +66 -0
- package/esm/sdkClient/trackMethod.js +52 -0
- package/esm/sdkFactory/index.js +8 -45
- package/esm/sdkManager/index.js +4 -4
- package/esm/services/splitApi.js +18 -13
- package/esm/services/splitHttpClient.js +1 -1
- package/esm/storages/AbstractSplitsCacheAsync.js +1 -1
- package/esm/storages/AbstractSplitsCacheSync.js +1 -1
- package/esm/storages/KeyBuilder.js +12 -12
- package/esm/storages/KeyBuilderCS.js +12 -12
- package/esm/storages/KeyBuilderSS.js +14 -14
- package/esm/storages/getRolloutPlan.js +1 -1
- package/esm/storages/inLocalStorage/RBSegmentsCacheInLocal.js +1 -1
- package/esm/storages/inMemory/ImpressionCountsCacheInMemory.js +1 -1
- package/esm/storages/inMemory/RBSegmentsCacheInMemory.js +1 -1
- package/esm/storages/inMemory/TelemetryCacheInMemory.js +2 -2
- package/esm/storages/inRedis/EventsCacheInRedis.js +1 -1
- package/esm/storages/inRedis/ImpressionCountsCacheInRedis.js +4 -4
- package/esm/storages/inRedis/RBSegmentsCacheInRedis.js +1 -1
- package/esm/storages/inRedis/RedisAdapter.js +7 -7
- package/esm/storages/inRedis/SplitsCacheInRedis.js +4 -4
- package/esm/storages/inRedis/TelemetryCacheInRedis.js +7 -7
- package/esm/storages/inRedis/UniqueKeysCacheInRedis.js +1 -1
- package/esm/storages/pluggable/EventsCachePluggable.js +1 -1
- package/esm/storages/pluggable/ImpressionCountsCachePluggable.js +5 -5
- package/esm/storages/pluggable/RBSegmentsCachePluggable.js +1 -1
- package/esm/storages/pluggable/SplitsCachePluggable.js +2 -2
- package/esm/storages/pluggable/TelemetryCachePluggable.js +7 -7
- package/esm/storages/pluggable/UniqueKeysCachePluggable.js +1 -1
- package/esm/storages/pluggable/index.js +2 -2
- package/esm/storages/pluggable/wrapperAdapter.js +1 -1
- package/esm/storages/setRolloutPlan.js +1 -1
- package/esm/storages/utils.js +6 -6
- package/esm/sync/offline/splitsParser/parseCondition.js +1 -1
- package/esm/sync/polling/fetchers/splitChangesFetcher.js +24 -15
- package/esm/sync/polling/pollingManagerCS.js +11 -11
- package/esm/sync/polling/pollingManagerSS.js +13 -13
- package/esm/sync/polling/syncTasks/definitionsSyncTask.js +8 -0
- package/esm/sync/polling/updaters/{splitChangesUpdater.js → definitionChangesUpdater.js} +67 -59
- package/esm/sync/polling/updaters/mySegmentsUpdater.js +2 -2
- package/esm/sync/polling/updaters/segmentChangesUpdater.js +7 -7
- package/esm/sync/streaming/SSEClient/index.js +2 -2
- package/esm/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +2 -2
- package/esm/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.js +2 -2
- package/esm/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +4 -4
- package/esm/sync/streaming/parseUtils.js +10 -10
- package/esm/sync/streaming/pushManager.js +3 -3
- package/esm/sync/submitters/impressionsSubmitter.js +6 -6
- package/esm/sync/submitters/submitter.js +1 -1
- package/esm/sync/syncManagerOnline.js +5 -2
- package/esm/trackers/eventTracker.js +10 -12
- package/esm/trackers/impressionObserver/buildKey.js +1 -1
- package/esm/trackers/impressionsTracker.js +38 -21
- package/esm/trackers/uniqueKeysTracker.js +1 -1
- package/esm/utils/EventEmitter.js +387 -0
- package/esm/utils/filter/bloomFilter.js +33 -0
- package/esm/utils/inputValidation/apiKey.js +1 -1
- package/esm/utils/inputValidation/attribute.js +2 -2
- package/esm/utils/inputValidation/{split.js → definition.js} +8 -8
- package/esm/utils/inputValidation/definitionExistence.js +15 -0
- package/esm/utils/inputValidation/definitions.js +21 -0
- package/esm/utils/inputValidation/index.js +3 -3
- package/esm/utils/inputValidation/isOperational.js +4 -4
- package/esm/utils/inputValidation/target.js +18 -0
- package/esm/utils/labels/index.js +2 -2
- package/esm/utils/promise/timeout.js +1 -1
- package/esm/utils/settingsValidation/splitFilters.js +4 -4
- package/esm/utils/settingsValidation/url.js +5 -5
- package/package.json +15 -6
- package/src/dtos/types.ts +65 -70
- package/src/evaluator/Engine.ts +4 -4
- package/src/evaluator/combiners/and.ts +3 -3
- package/src/evaluator/combiners/ifelseif.ts +2 -2
- package/src/evaluator/condition/engineUtils.ts +2 -2
- package/src/evaluator/condition/index.ts +3 -3
- package/src/evaluator/fallbackConfigsCalculator/fallbackSanitizer/index.ts +76 -0
- package/src/evaluator/fallbackConfigsCalculator/index.ts +24 -0
- package/src/evaluator/fallbackTreatmentsCalculator/fallbackSanitizer/index.ts +5 -7
- package/src/evaluator/fallbackTreatmentsCalculator/index.ts +27 -41
- package/src/evaluator/index.ts +80 -45
- package/src/evaluator/matchers/dependency.ts +2 -2
- package/src/evaluator/matchers/matcherTypes.ts +2 -2
- package/src/evaluator/matchers/prerequisites.ts +4 -4
- package/src/evaluator/matchers/rbsegment.ts +2 -2
- package/src/evaluator/matchers/whitelist.ts +2 -2
- package/src/evaluator/matchersTransform/index.ts +2 -2
- package/src/evaluator/matchersTransform/whitelist.ts +2 -2
- package/src/evaluator/parser/index.ts +4 -4
- package/src/evaluator/treatments/index.ts +2 -2
- package/src/evaluator/types.ts +6 -6
- package/src/evaluator/value/index.ts +1 -1
- package/src/integrations/pluggable.ts +1 -1
- package/src/listeners/browser.ts +11 -8
- package/src/listeners/node.ts +2 -5
- package/src/logger/constants.ts +11 -17
- package/src/logger/messages/debug.ts +5 -6
- package/src/logger/messages/error.ts +3 -3
- package/src/logger/messages/info.ts +1 -3
- package/src/logger/messages/warn.ts +8 -8
- package/src/platform/browser.ts +14 -0
- package/src/platform/getEventSource/browser.ts +4 -0
- package/src/platform/getEventSource/eventsource.js +519 -0
- package/src/platform/getEventSource/node.ts +23 -0
- package/src/platform/getFetch/browser.ts +5 -0
- package/src/platform/getFetch/node.ts +27 -0
- package/src/platform/getOptions/node.ts +24 -0
- package/src/platform/node.ts +16 -0
- package/src/readiness/constants.ts +1 -0
- package/src/sdkClient/client.ts +11 -41
- package/src/sdkClient/clientInputValidation.ts +44 -84
- package/src/sdkClient/sdkClient.ts +5 -54
- package/src/sdkClient/sdkLifecycle.ts +78 -0
- package/src/sdkClient/trackMethod.ts +59 -0
- package/src/sdkFactory/index.ts +10 -54
- package/src/sdkFactory/types.ts +19 -16
- package/src/sdkManager/index.ts +9 -9
- package/src/services/splitApi.ts +6 -0
- package/src/services/types.ts +3 -2
- package/src/storages/AbstractSplitsCacheAsync.ts +7 -7
- package/src/storages/AbstractSplitsCacheSync.ts +10 -10
- package/src/storages/inLocalStorage/RBSegmentsCacheInLocal.ts +2 -2
- package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +6 -6
- package/src/storages/inMemory/RBSegmentsCacheInMemory.ts +2 -2
- package/src/storages/inMemory/SplitsCacheInMemory.ts +5 -5
- package/src/storages/inMemory/TelemetryCacheInMemory.ts +2 -2
- package/src/storages/inRedis/RBSegmentsCacheInRedis.ts +2 -2
- package/src/storages/inRedis/SplitsCacheInRedis.ts +9 -9
- package/src/storages/pluggable/RBSegmentsCachePluggable.ts +2 -2
- package/src/storages/pluggable/SplitsCachePluggable.ts +9 -9
- package/src/storages/types.ts +21 -16
- package/src/sync/offline/splitsParser/parseCondition.ts +2 -2
- package/src/sync/offline/splitsParser/splitsParserFromSettings.ts +3 -3
- package/src/sync/offline/splitsParser/types.ts +6 -3
- package/src/sync/offline/syncManagerOffline.ts +2 -2
- package/src/sync/offline/syncTasks/fromObjectSyncTask.ts +6 -6
- package/src/sync/polling/fetchers/splitChangesFetcher.ts +57 -22
- package/src/sync/polling/fetchers/types.ts +5 -3
- package/src/sync/polling/pollingManagerCS.ts +12 -10
- package/src/sync/polling/pollingManagerSS.ts +15 -13
- package/src/sync/polling/syncTasks/{splitsSyncTask.ts → definitionsSyncTask.ts} +10 -11
- package/src/sync/polling/types.ts +3 -3
- package/src/sync/polling/updaters/{splitChangesUpdater.ts → definitionChangesUpdater.ts} +77 -68
- package/src/sync/polling/updaters/mySegmentsUpdater.ts +2 -2
- package/src/sync/polling/updaters/segmentChangesUpdater.ts +7 -7
- package/src/sync/streaming/UpdateWorkers/SplitsUpdateWorker.ts +6 -6
- package/src/sync/streaming/parseUtils.ts +12 -12
- package/src/sync/streaming/pushManager.ts +3 -3
- package/src/sync/submitters/impressionsSubmitter.ts +9 -9
- package/src/sync/submitters/types.ts +3 -0
- package/src/sync/syncManagerOnline.ts +6 -2
- package/src/trackers/eventTracker.ts +7 -10
- package/src/trackers/impressionsTracker.ts +42 -26
- package/src/trackers/types.ts +3 -1
- package/src/utils/EventEmitter.js +444 -0
- package/src/utils/filter/bloomFilter.ts +38 -0
- package/src/utils/inputValidation/definition.ts +27 -0
- package/src/utils/inputValidation/definitionExistence.ts +19 -0
- package/src/utils/inputValidation/definitions.ts +21 -0
- package/src/utils/inputValidation/index.ts +3 -3
- package/src/utils/inputValidation/isOperational.ts +4 -4
- package/src/utils/inputValidation/target.ts +21 -0
- package/src/utils/labels/index.ts +2 -2
- package/src/utils/settingsValidation/splitFilters.ts +3 -3
- package/types/splitio.d.ts +202 -9
- package/cjs/sync/polling/syncTasks/splitsSyncTask.js +0 -13
- package/cjs/utils/inputValidation/splits.js +0 -25
- package/esm/sync/polling/syncTasks/splitsSyncTask.js +0 -9
- package/esm/utils/inputValidation/splitExistence.js +0 -15
- package/esm/utils/inputValidation/splits.js +0 -21
- package/src/utils/inputValidation/split.ts +0 -27
- package/src/utils/inputValidation/splitExistence.ts +0 -19
- package/src/utils/inputValidation/splits.ts +0 -21
|
@@ -2,7 +2,7 @@ import { isFiniteNumber, isNaNNumber } from '../../utils/lang';
|
|
|
2
2
|
import { KeyBuilder } from '../KeyBuilder';
|
|
3
3
|
import { IPluggableStorageWrapper } from '../types';
|
|
4
4
|
import { ILogger } from '../../logger/types';
|
|
5
|
-
import {
|
|
5
|
+
import { IDefinition, ISplitFiltersValidation } from '../../dtos/types';
|
|
6
6
|
import { LOG_PREFIX } from './constants';
|
|
7
7
|
import { AbstractSplitsCacheAsync } from '../AbstractSplitsCacheAsync';
|
|
8
8
|
import { returnDifference } from '../../utils/lang/sets';
|
|
@@ -31,14 +31,14 @@ export class SplitsCachePluggable extends AbstractSplitsCacheAsync {
|
|
|
31
31
|
this.flagSetsFilter = splitFiltersValidation ? splitFiltersValidation.groupedFilters.bySet : [];
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
private _decrementCounts(split:
|
|
34
|
+
private _decrementCounts(split: IDefinition) {
|
|
35
35
|
const ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
|
|
36
36
|
return this.wrapper.decr(ttKey).then(count => {
|
|
37
37
|
if (count === 0) return this.wrapper.del(ttKey);
|
|
38
38
|
});
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
private _incrementCounts(split:
|
|
41
|
+
private _incrementCounts(split: IDefinition) {
|
|
42
42
|
const ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
|
|
43
43
|
return this.wrapper.incr(ttKey);
|
|
44
44
|
}
|
|
@@ -66,13 +66,13 @@ export class SplitsCachePluggable extends AbstractSplitsCacheAsync {
|
|
|
66
66
|
* The returned promise is resolved when the operation success
|
|
67
67
|
* or rejected if it fails (e.g., wrapper operation fails)
|
|
68
68
|
*/
|
|
69
|
-
addSplit(split:
|
|
69
|
+
addSplit(split: IDefinition): Promise<boolean> {
|
|
70
70
|
const name = split.name;
|
|
71
71
|
const splitKey = this.keys.buildSplitKey(name);
|
|
72
72
|
return this.wrapper.get(splitKey).then(splitFromStorage => {
|
|
73
73
|
|
|
74
74
|
// handling parsing error
|
|
75
|
-
let parsedPreviousSplit:
|
|
75
|
+
let parsedPreviousSplit: IDefinition, stringifiedNewSplit;
|
|
76
76
|
try {
|
|
77
77
|
parsedPreviousSplit = splitFromStorage ? JSON.parse(splitFromStorage) : undefined;
|
|
78
78
|
stringifiedNewSplit = JSON.stringify(split);
|
|
@@ -112,7 +112,7 @@ export class SplitsCachePluggable extends AbstractSplitsCacheAsync {
|
|
|
112
112
|
* The returned promise is resolved with the split definition or null if it's not defined,
|
|
113
113
|
* or rejected if wrapper operation fails.
|
|
114
114
|
*/
|
|
115
|
-
getSplit(name: string): Promise<
|
|
115
|
+
getSplit(name: string): Promise<IDefinition | null> {
|
|
116
116
|
return this.wrapper.get(this.keys.buildSplitKey(name))
|
|
117
117
|
.then(maybeSplit => maybeSplit && JSON.parse(maybeSplit));
|
|
118
118
|
}
|
|
@@ -122,11 +122,11 @@ export class SplitsCachePluggable extends AbstractSplitsCacheAsync {
|
|
|
122
122
|
* The returned promise is resolved with a map of split names to their split definition or null if it's not defined,
|
|
123
123
|
* or rejected if wrapper operation fails.
|
|
124
124
|
*/
|
|
125
|
-
getSplits(names: string[]): Promise<Record<string,
|
|
125
|
+
getSplits(names: string[]): Promise<Record<string, IDefinition | null>> {
|
|
126
126
|
const keys = names.map(name => this.keys.buildSplitKey(name));
|
|
127
127
|
|
|
128
128
|
return this.wrapper.getMany(keys).then(splitDefinitions => {
|
|
129
|
-
const splits: Record<string,
|
|
129
|
+
const splits: Record<string, IDefinition | null> = {};
|
|
130
130
|
names.forEach((name, idx) => {
|
|
131
131
|
const split = splitDefinitions[idx];
|
|
132
132
|
splits[name] = split && JSON.parse(split);
|
|
@@ -140,7 +140,7 @@ export class SplitsCachePluggable extends AbstractSplitsCacheAsync {
|
|
|
140
140
|
* The returned promise is resolved with the list of split definitions,
|
|
141
141
|
* or rejected if wrapper operation fails.
|
|
142
142
|
*/
|
|
143
|
-
getAll(): Promise<
|
|
143
|
+
getAll(): Promise<IDefinition[]> {
|
|
144
144
|
return this.wrapper.getKeysByPrefix(this.keys.buildSplitKeyPrefix())
|
|
145
145
|
.then((listOfKeys) => this.wrapper.getMany(listOfKeys))
|
|
146
146
|
.then((splitDefinitions) => splitDefinitions.map((splitDefinition) => {
|
package/src/storages/types.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import SplitIO from '../../types/splitio';
|
|
2
|
-
import { MaybeThenable,
|
|
2
|
+
import { MaybeThenable, IDefinition, IRBSegment, IMySegmentsResponse, IMembershipsResponse, ISegmentChangesResponse } from '../dtos/types';
|
|
3
|
+
import { ISplitChangesResponse } from '../sync/polling/fetchers/splitChangesFetcher';
|
|
3
4
|
import { MySegmentsData } from '../sync/polling/types';
|
|
4
5
|
import { EventDataType, HttpErrors, HttpLatencies, ImpressionDataType, LastSync, Method, MethodExceptions, MethodLatencies, MultiMethodExceptions, MultiMethodLatencies, MultiConfigs, OperationType, StoredEventWithMetadata, StoredImpressionWithMetadata, StreamingEvent, UniqueKeysPayloadCs, UniqueKeysPayloadSs, TelemetryUsageStatsPayload, UpdatesFromSSEEnum } from '../sync/submitters/types';
|
|
5
6
|
import { ISettings } from '../types';
|
|
@@ -194,12 +195,12 @@ export interface IPluggableStorageWrapper {
|
|
|
194
195
|
/** Splits cache */
|
|
195
196
|
|
|
196
197
|
export interface ISplitsCacheBase {
|
|
197
|
-
update(toAdd:
|
|
198
|
-
getSplit(name: string): MaybeThenable<
|
|
199
|
-
getSplits(names: string[]): MaybeThenable<Record<string,
|
|
198
|
+
update(toAdd: IDefinition[], toRemove: string[], changeNumber: number): MaybeThenable<boolean>,
|
|
199
|
+
getSplit(name: string): MaybeThenable<IDefinition | null>,
|
|
200
|
+
getSplits(names: string[]): MaybeThenable<Record<string, IDefinition | null>>, // `fetchMany` in spec
|
|
200
201
|
// should never reject or throw an exception. Instead return -1 by default, assuming no splits are present in the storage.
|
|
201
202
|
getChangeNumber(): MaybeThenable<number>,
|
|
202
|
-
getAll(): MaybeThenable<
|
|
203
|
+
getAll(): MaybeThenable<IDefinition[]>,
|
|
203
204
|
getSplitNames(): MaybeThenable<string[]>,
|
|
204
205
|
// should never reject or throw an exception. Instead return true by default, asssuming the TT might exist.
|
|
205
206
|
trafficTypeExists(trafficType: string): MaybeThenable<boolean>,
|
|
@@ -211,11 +212,11 @@ export interface ISplitsCacheBase {
|
|
|
211
212
|
}
|
|
212
213
|
|
|
213
214
|
export interface ISplitsCacheSync extends ISplitsCacheBase {
|
|
214
|
-
update(toAdd:
|
|
215
|
-
getSplit(name: string):
|
|
216
|
-
getSplits(names: string[]): Record<string,
|
|
215
|
+
update(toAdd: IDefinition[], toRemove: string[], changeNumber: number): boolean,
|
|
216
|
+
getSplit(name: string): IDefinition | null,
|
|
217
|
+
getSplits(names: string[]): Record<string, IDefinition | null>,
|
|
217
218
|
getChangeNumber(): number,
|
|
218
|
-
getAll():
|
|
219
|
+
getAll(): IDefinition[],
|
|
219
220
|
getSplitNames(): string[],
|
|
220
221
|
trafficTypeExists(trafficType: string): boolean,
|
|
221
222
|
usesSegments(): boolean,
|
|
@@ -225,11 +226,11 @@ export interface ISplitsCacheSync extends ISplitsCacheBase {
|
|
|
225
226
|
}
|
|
226
227
|
|
|
227
228
|
export interface ISplitsCacheAsync extends ISplitsCacheBase {
|
|
228
|
-
update(toAdd:
|
|
229
|
-
getSplit(name: string): Promise<
|
|
230
|
-
getSplits(names: string[]): Promise<Record<string,
|
|
229
|
+
update(toAdd: IDefinition[], toRemove: string[], changeNumber: number): Promise<boolean>,
|
|
230
|
+
getSplit(name: string): Promise<IDefinition | null>,
|
|
231
|
+
getSplits(names: string[]): Promise<Record<string, IDefinition | null>>,
|
|
231
232
|
getChangeNumber(): Promise<number>,
|
|
232
|
-
getAll(): Promise<
|
|
233
|
+
getAll(): Promise<IDefinition[]>,
|
|
233
234
|
getSplitNames(): Promise<string[]>,
|
|
234
235
|
trafficTypeExists(trafficType: string): Promise<boolean>,
|
|
235
236
|
usesSegments(): Promise<boolean>,
|
|
@@ -241,7 +242,7 @@ export interface ISplitsCacheAsync extends ISplitsCacheBase {
|
|
|
241
242
|
/** Rule-Based Segments cache */
|
|
242
243
|
|
|
243
244
|
export interface IRBSegmentsCacheBase {
|
|
244
|
-
update(toAdd: IRBSegment[], toRemove:
|
|
245
|
+
update(toAdd: IRBSegment[], toRemove: string[], changeNumber: number): MaybeThenable<boolean>,
|
|
245
246
|
get(name: string): MaybeThenable<IRBSegment | null>,
|
|
246
247
|
getChangeNumber(): MaybeThenable<number>,
|
|
247
248
|
clear(): MaybeThenable<boolean | void>,
|
|
@@ -249,7 +250,7 @@ export interface IRBSegmentsCacheBase {
|
|
|
249
250
|
}
|
|
250
251
|
|
|
251
252
|
export interface IRBSegmentsCacheSync extends IRBSegmentsCacheBase {
|
|
252
|
-
update(toAdd: IRBSegment[], toRemove:
|
|
253
|
+
update(toAdd: IRBSegment[], toRemove: string[], changeNumber: number): boolean,
|
|
253
254
|
get(name: string): IRBSegment | null,
|
|
254
255
|
getChangeNumber(): number,
|
|
255
256
|
getAll(): IRBSegment[],
|
|
@@ -260,7 +261,7 @@ export interface IRBSegmentsCacheSync extends IRBSegmentsCacheBase {
|
|
|
260
261
|
}
|
|
261
262
|
|
|
262
263
|
export interface IRBSegmentsCacheAsync extends IRBSegmentsCacheBase {
|
|
263
|
-
update(toAdd: IRBSegment[], toRemove:
|
|
264
|
+
update(toAdd: IRBSegment[], toRemove: string[], changeNumber: number): Promise<boolean>,
|
|
264
265
|
get(name: string): Promise<IRBSegment | null>,
|
|
265
266
|
getChangeNumber(): Promise<number>,
|
|
266
267
|
clear(): Promise<boolean | void>,
|
|
@@ -527,6 +528,10 @@ export interface IStorageFactoryParams {
|
|
|
527
528
|
* For emitting SDK_READY_FROM_CACHE event in consumer mode with Redis to allow immediate evaluations
|
|
528
529
|
*/
|
|
529
530
|
onReadyFromCacheCb: () => void,
|
|
531
|
+
/**
|
|
532
|
+
* If true, telemetry will not be recorded.
|
|
533
|
+
*/
|
|
534
|
+
disableTelemetry?: boolean,
|
|
530
535
|
}
|
|
531
536
|
|
|
532
537
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IDefinitionCondition } from '../../../dtos/types';
|
|
2
2
|
import { isString } from '../../../utils/lang';
|
|
3
3
|
|
|
4
4
|
export interface IMockSplitEntry {
|
|
@@ -7,7 +7,7 @@ export interface IMockSplitEntry {
|
|
|
7
7
|
config?: string
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
export function parseCondition(data: IMockSplitEntry):
|
|
10
|
+
export function parseCondition(data: IMockSplitEntry): IDefinitionCondition {
|
|
11
11
|
const treatment = data.treatment;
|
|
12
12
|
|
|
13
13
|
if (data.keys) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IDefinitionPartial } from './types';
|
|
2
2
|
import SplitIO from '../../../../types/splitio';
|
|
3
3
|
import { isObject, forOwn, merge } from '../../../utils/lang';
|
|
4
4
|
import { parseCondition } from './parseCondition';
|
|
@@ -41,12 +41,12 @@ export function splitsParserFromSettingsFactory() {
|
|
|
41
41
|
*
|
|
42
42
|
* @param settings - validated object with mocked features mapping.
|
|
43
43
|
*/
|
|
44
|
-
return function splitsParserFromSettings(settings: Pick<SplitIO.ISettings, 'features'>): false | Record<string,
|
|
44
|
+
return function splitsParserFromSettings(settings: Pick<SplitIO.ISettings, 'features'>): false | Record<string, IDefinitionPartial> {
|
|
45
45
|
const features = settings.features as SplitIO.MockedFeaturesMap || {};
|
|
46
46
|
|
|
47
47
|
if (!mockUpdated(features)) return false;
|
|
48
48
|
|
|
49
|
-
const splitObjects: Record<string,
|
|
49
|
+
const splitObjects: Record<string, IDefinitionPartial> = {};
|
|
50
50
|
|
|
51
51
|
forOwn(features, (data, splitName) => {
|
|
52
52
|
let treatment = data;
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IDefinition } from '../../../dtos/types';
|
|
2
2
|
import { ISettings } from '../../../types';
|
|
3
3
|
|
|
4
|
-
//
|
|
5
|
-
export type
|
|
4
|
+
// Split definition used in offline mode
|
|
5
|
+
export type IDefinitionPartial = Pick<IDefinition, 'conditions' | 'configurations' | 'trafficTypeName'>
|
|
6
|
+
|
|
7
|
+
// Analog to `IDefinitionChangesFetcher` used by `definitionChangesUpdaterFactory`
|
|
8
|
+
export type IDefinitionsParser = (settings: ISettings) => false | Record<string, IDefinitionPartial>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ISyncManagerCS } from '../types';
|
|
2
2
|
import { fromObjectSyncTaskFactory } from './syncTasks/fromObjectSyncTask';
|
|
3
3
|
import { objectAssign } from '../../utils/lang/objectAssign';
|
|
4
|
-
import {
|
|
4
|
+
import { IDefinitionsParser } from './splitsParser/types';
|
|
5
5
|
import { IReadinessManager } from '../../readiness/types';
|
|
6
6
|
import { SDK_SEGMENTS_ARRIVED } from '../../readiness/constants';
|
|
7
7
|
import { ISdkFactoryContextSync } from '../../sdkFactory/types';
|
|
@@ -17,7 +17,7 @@ function flush() {
|
|
|
17
17
|
* @param splitsParser - e.g., `splitsParserFromFile`, `splitsParserFromSettings`.
|
|
18
18
|
*/
|
|
19
19
|
export function syncManagerOfflineFactory(
|
|
20
|
-
splitsParserFactory: () =>
|
|
20
|
+
splitsParserFactory: () => IDefinitionsParser
|
|
21
21
|
): (params: ISdkFactoryContextSync) => ISyncManagerCS {
|
|
22
22
|
|
|
23
23
|
/**
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { forOwn } from '../../../utils/lang';
|
|
2
2
|
import { IReadinessManager } from '../../../readiness/types';
|
|
3
3
|
import { IStorageSync } from '../../../storages/types';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { IDefinitionsParser, IDefinitionPartial } from '../splitsParser/types';
|
|
5
|
+
import { IDefinition } from '../../../dtos/types';
|
|
6
6
|
import { syncTaskFactory } from '../../syncTask';
|
|
7
7
|
import { ISyncTask } from '../../types';
|
|
8
8
|
import { ISettings } from '../../../types';
|
|
@@ -14,7 +14,7 @@ import { SYNC_OFFLINE_DATA, ERROR_SYNC_OFFLINE_LOADING } from '../../../logger/c
|
|
|
14
14
|
* Offline equivalent of `splitChangesUpdaterFactory`
|
|
15
15
|
*/
|
|
16
16
|
export function fromObjectUpdaterFactory(
|
|
17
|
-
splitsParser:
|
|
17
|
+
splitsParser: IDefinitionsParser,
|
|
18
18
|
storage: Pick<IStorageSync, 'splits' | 'validateCache'>,
|
|
19
19
|
readiness: IReadinessManager,
|
|
20
20
|
settings: ISettings,
|
|
@@ -24,9 +24,9 @@ export function fromObjectUpdaterFactory(
|
|
|
24
24
|
let startingUp = true;
|
|
25
25
|
|
|
26
26
|
return function objectUpdater() {
|
|
27
|
-
const splits:
|
|
27
|
+
const splits: IDefinition[] = [];
|
|
28
28
|
let loadError = null;
|
|
29
|
-
let splitsMock: false | Record<string,
|
|
29
|
+
let splitsMock: false | Record<string, IDefinitionPartial> = {};
|
|
30
30
|
try {
|
|
31
31
|
splitsMock = splitsParser(settings);
|
|
32
32
|
} catch (err) {
|
|
@@ -80,7 +80,7 @@ export function fromObjectUpdaterFactory(
|
|
|
80
80
|
* PollingManager in Offline mode
|
|
81
81
|
*/
|
|
82
82
|
export function fromObjectSyncTaskFactory(
|
|
83
|
-
splitsParser:
|
|
83
|
+
splitsParser: IDefinitionsParser,
|
|
84
84
|
storage: Pick<IStorageSync, 'splits' | 'validateCache'>,
|
|
85
85
|
readiness: IReadinessManager,
|
|
86
86
|
settings: ISettings
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { ISettings } from '../../../types';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { IStorageBase } from '../../../storages/types';
|
|
2
|
+
import { IDefinition, IRBSegment, IDefinitionChangesResponse } from '../../../dtos/types';
|
|
3
|
+
import { IResponse } from '../../../services/types';
|
|
5
4
|
import { FLAG_SPEC_VERSION } from '../../../utils/constants';
|
|
6
5
|
import { base } from '../../../utils/settingsValidation';
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
6
|
+
import { IDefinitionChangesFetcher } from './types';
|
|
7
|
+
import { LOG_PREFIX_SYNC } from '../../../logger/constants';
|
|
9
8
|
import { checkIfServerSide } from '../../../utils/key';
|
|
9
|
+
import { ISdkFactoryContextSync } from '../../../sdkFactory/types';
|
|
10
10
|
|
|
11
11
|
const PROXY_CHECK_INTERVAL_MILLIS_CS = 60 * 60 * 1000; // 1 hour in Client Side
|
|
12
12
|
const PROXY_CHECK_INTERVAL_MILLIS_SS = 24 * PROXY_CHECK_INTERVAL_MILLIS_CS; // 24 hours in Server Side
|
|
@@ -15,25 +15,59 @@ function sdkEndpointOverridden(settings: ISettings) {
|
|
|
15
15
|
return settings.urls.sdk !== base.urls.sdk;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
export type ISplit = IDefinition;
|
|
19
|
+
|
|
20
|
+
/** JSON response of `/splitChanges` */
|
|
21
|
+
export interface ISplitChangesResponse {
|
|
22
|
+
ff?: {
|
|
23
|
+
t: number,
|
|
24
|
+
s?: number,
|
|
25
|
+
d: ISplit[]
|
|
26
|
+
},
|
|
27
|
+
rbs?: {
|
|
28
|
+
t: number,
|
|
29
|
+
s?: number,
|
|
30
|
+
d: IRBSegment[]
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** JSON response of `/splitChanges` for flag spec version 1.2 or below */
|
|
35
|
+
export interface ISplitChangesLegacyResponse {
|
|
36
|
+
till: number,
|
|
37
|
+
since?: number,
|
|
38
|
+
splits: ISplit[]
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function isSplitChangesLegacyResponse(data: ISplitChangesResponse | ISplitChangesLegacyResponse): data is ISplitChangesLegacyResponse {
|
|
42
|
+
return (data as ISplitChangesLegacyResponse).splits != null;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function partitionByStatus<T extends { status?: string; name: string }>(items: T[], till: number, since?: number) {
|
|
46
|
+
const updated: T[] = [], removed: string[] = [];
|
|
47
|
+
items.forEach(item => item.status === 'ARCHIVED' ? removed.push(item.name) : updated.push(item));
|
|
48
|
+
return { updated, removed, till, since };
|
|
49
|
+
}
|
|
50
|
+
|
|
18
51
|
/**
|
|
19
52
|
* Factory of SplitChanges fetcher.
|
|
20
53
|
* SplitChanges fetcher is a wrapper around `splitChanges` API service that parses the response and handle errors.
|
|
21
54
|
*/
|
|
22
55
|
// @TODO breaking: drop support for Split Proxy below v5.10.0 and simplify the implementation
|
|
23
|
-
export function splitChangesFetcherFactory(
|
|
56
|
+
export function splitChangesFetcherFactory(params: ISdkFactoryContextSync): IDefinitionChangesFetcher {
|
|
24
57
|
|
|
58
|
+
const { splitApi: { fetchSplitChanges }, settings, storage } = params;
|
|
25
59
|
const log = settings.log;
|
|
26
60
|
const PROXY_CHECK_INTERVAL_MILLIS = checkIfServerSide(settings) ? PROXY_CHECK_INTERVAL_MILLIS_SS : PROXY_CHECK_INTERVAL_MILLIS_CS;
|
|
27
61
|
let lastProxyCheckTimestamp: number | undefined;
|
|
28
62
|
|
|
29
|
-
|
|
63
|
+
function splitChangesFetcher(
|
|
30
64
|
since: number,
|
|
31
65
|
noCache?: boolean,
|
|
32
66
|
till?: number,
|
|
33
67
|
rbSince?: number,
|
|
34
68
|
// Optional decorator for `fetchSplitChanges` promise, such as timeout or time tracker
|
|
35
69
|
decorator?: (promise: Promise<IResponse>) => Promise<IResponse>
|
|
36
|
-
): Promise<
|
|
70
|
+
): Promise<IDefinitionChangesResponse> {
|
|
37
71
|
|
|
38
72
|
// Recheck proxy
|
|
39
73
|
if (lastProxyCheckTimestamp && (Date.now() - lastProxyCheckTimestamp) > PROXY_CHECK_INTERVAL_MILLIS) {
|
|
@@ -44,7 +78,7 @@ export function splitChangesFetcherFactory(fetchSplitChanges: IFetchSplitChanges
|
|
|
44
78
|
.catch((err) => {
|
|
45
79
|
// Handle proxy error with spec 1.3
|
|
46
80
|
if ((!err.statusCode || err.statusCode === 400) && sdkEndpointOverridden(settings) && settings.sync.flagSpecVersion === FLAG_SPEC_VERSION) {
|
|
47
|
-
log.error(
|
|
81
|
+
log.error(LOG_PREFIX_SYNC + 'Proxy error detected. Retrying with spec 1.2. If you are using Split Proxy, please upgrade to latest version');
|
|
48
82
|
lastProxyCheckTimestamp = Date.now();
|
|
49
83
|
settings.sync.flagSpecVersion = '1.2'; // fallback to 1.2 spec
|
|
50
84
|
return fetchSplitChanges(since, noCache, till); // retry request without rbSince
|
|
@@ -56,31 +90,32 @@ export function splitChangesFetcherFactory(fetchSplitChanges: IFetchSplitChanges
|
|
|
56
90
|
|
|
57
91
|
return splitsPromise
|
|
58
92
|
.then(resp => resp.json())
|
|
59
|
-
.then(data => {
|
|
93
|
+
.then((data: ISplitChangesResponse | ISplitChangesLegacyResponse) => {
|
|
60
94
|
// Using flag spec version 1.2 or below
|
|
61
|
-
if (data
|
|
62
|
-
return {
|
|
63
|
-
ff: {
|
|
64
|
-
d: data.splits,
|
|
65
|
-
s: data.since,
|
|
66
|
-
t: data.till
|
|
67
|
-
}
|
|
68
|
-
};
|
|
95
|
+
if (isSplitChangesLegacyResponse(data)) {
|
|
96
|
+
return { d: partitionByStatus(data.splits || [], data.till, data.since) };
|
|
69
97
|
}
|
|
70
98
|
|
|
71
99
|
// Proxy recovery
|
|
72
100
|
if (lastProxyCheckTimestamp) {
|
|
73
|
-
log.info(
|
|
101
|
+
log.info(LOG_PREFIX_SYNC + 'Proxy error recovered');
|
|
74
102
|
lastProxyCheckTimestamp = undefined;
|
|
75
103
|
return splitChangesFetcher(-1, undefined, undefined, -1)
|
|
76
|
-
.then((splitChangesResponse:
|
|
104
|
+
.then((splitChangesResponse: IDefinitionChangesResponse) =>
|
|
77
105
|
Promise.all([storage.splits.clear(), storage.rbSegments.clear()])
|
|
78
106
|
.then(() => splitChangesResponse)
|
|
79
107
|
);
|
|
80
108
|
}
|
|
81
109
|
|
|
82
|
-
|
|
110
|
+
const { ff, rbs } = data;
|
|
111
|
+
|
|
112
|
+
return {
|
|
113
|
+
d: ff?.d ? partitionByStatus(ff.d, ff.t, ff.s) : undefined,
|
|
114
|
+
rbs: rbs?.d ? partitionByStatus(rbs.d, rbs.t, rbs.s) : undefined,
|
|
115
|
+
};
|
|
83
116
|
});
|
|
84
|
-
}
|
|
117
|
+
}
|
|
85
118
|
|
|
119
|
+
splitChangesFetcher.type = 'feature flags' as const;
|
|
120
|
+
return splitChangesFetcher;
|
|
86
121
|
}
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IDefinitionChangesResponse, ISegmentChangesResponse, IMembershipsResponse } from '../../../dtos/types';
|
|
2
2
|
import { IResponse } from '../../../services/types';
|
|
3
3
|
|
|
4
|
-
export type
|
|
4
|
+
export type IDefinitionChangesFetcher = ((
|
|
5
5
|
since: number,
|
|
6
6
|
noCache?: boolean,
|
|
7
7
|
till?: number,
|
|
8
8
|
rbSince?: number,
|
|
9
9
|
decorator?: (promise: Promise<IResponse>) => Promise<IResponse>
|
|
10
|
-
) => Promise<
|
|
10
|
+
) => Promise<IDefinitionChangesResponse>) & {
|
|
11
|
+
type: 'configs' | 'feature flags'
|
|
12
|
+
}
|
|
11
13
|
|
|
12
14
|
export type ISegmentChangesFetcher = (
|
|
13
15
|
since: number,
|
|
@@ -3,26 +3,28 @@ import { forOwn } from '../../utils/lang';
|
|
|
3
3
|
import { IReadinessManager } from '../../readiness/types';
|
|
4
4
|
import { IStorageSync } from '../../storages/types';
|
|
5
5
|
import { mySegmentsSyncTaskFactory } from './syncTasks/mySegmentsSyncTask';
|
|
6
|
-
import {
|
|
6
|
+
import { definitionsSyncTaskFactory } from './syncTasks/definitionsSyncTask';
|
|
7
7
|
import { getMatching } from '../../utils/key';
|
|
8
8
|
import { SDK_SPLITS_ARRIVED, SDK_SEGMENTS_ARRIVED } from '../../readiness/constants';
|
|
9
9
|
import { POLLING_SMART_PAUSING, POLLING_START, POLLING_STOP } from '../../logger/constants';
|
|
10
10
|
import { ISdkFactoryContextSync } from '../../sdkFactory/types';
|
|
11
11
|
import { usesSegmentsSync } from '../../storages/AbstractSplitsCacheSync';
|
|
12
12
|
import { SdkUpdateMetadata } from '../../../types/splitio';
|
|
13
|
+
import { IDefinitionChangesFetcher } from './fetchers/types';
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* Expose start / stop mechanism for polling data from services.
|
|
16
17
|
* For client-side API with multiple clients.
|
|
17
18
|
*/
|
|
18
19
|
export function pollingManagerCSFactory(
|
|
19
|
-
params: ISdkFactoryContextSync
|
|
20
|
+
params: ISdkFactoryContextSync,
|
|
21
|
+
definitionChangesFetcher: IDefinitionChangesFetcher
|
|
20
22
|
): IPollingManagerCS {
|
|
21
23
|
|
|
22
24
|
const { splitApi, storage, readiness, settings } = params;
|
|
23
25
|
const log = settings.log;
|
|
24
26
|
|
|
25
|
-
const
|
|
27
|
+
const definitionsSyncTask = definitionsSyncTaskFactory(definitionChangesFetcher, storage, readiness, settings, true);
|
|
26
28
|
|
|
27
29
|
// Map of matching keys to their corresponding MySegmentsSyncTask.
|
|
28
30
|
const mySegmentsSyncTasks: Record<string, IMySegmentsSyncTask> = {};
|
|
@@ -44,7 +46,7 @@ export function pollingManagerCSFactory(
|
|
|
44
46
|
|
|
45
47
|
// smart pausing
|
|
46
48
|
readiness.splits.on(SDK_SPLITS_ARRIVED, () => {
|
|
47
|
-
if (!
|
|
49
|
+
if (!definitionsSyncTask.isRunning()) return; // noop if not doing polling
|
|
48
50
|
const usingSegments = usesSegmentsSync(storage);
|
|
49
51
|
if (usingSegments !== mySegmentsSyncTask.isRunning()) {
|
|
50
52
|
log.info(POLLING_SMART_PAUSING, [usingSegments ? 'ON' : 'OFF']);
|
|
@@ -71,14 +73,14 @@ export function pollingManagerCSFactory(
|
|
|
71
73
|
}
|
|
72
74
|
|
|
73
75
|
return {
|
|
74
|
-
|
|
76
|
+
definitionsSyncTask,
|
|
75
77
|
segmentsSyncTask: mySegmentsSyncTask,
|
|
76
78
|
|
|
77
79
|
// Start periodic fetching (polling)
|
|
78
80
|
start() {
|
|
79
81
|
log.info(POLLING_START);
|
|
80
82
|
|
|
81
|
-
|
|
83
|
+
definitionsSyncTask.start();
|
|
82
84
|
if (usesSegmentsSync(storage)) startMySegmentsSyncTasks();
|
|
83
85
|
},
|
|
84
86
|
|
|
@@ -86,16 +88,16 @@ export function pollingManagerCSFactory(
|
|
|
86
88
|
stop() {
|
|
87
89
|
log.info(POLLING_STOP);
|
|
88
90
|
|
|
89
|
-
if (
|
|
91
|
+
if (definitionsSyncTask.isRunning()) definitionsSyncTask.stop();
|
|
90
92
|
stopMySegmentsSyncTasks();
|
|
91
93
|
},
|
|
92
94
|
|
|
93
95
|
// Used by SyncManager to know if running in polling mode.
|
|
94
|
-
isRunning:
|
|
96
|
+
isRunning: definitionsSyncTask.isRunning,
|
|
95
97
|
|
|
96
|
-
// fetch
|
|
98
|
+
// fetch definitions and segments
|
|
97
99
|
syncAll() {
|
|
98
|
-
const promises = [
|
|
100
|
+
const promises = [definitionsSyncTask.execute()];
|
|
99
101
|
forOwn(mySegmentsSyncTasks, (mySegmentsSyncTask) => {
|
|
100
102
|
promises.push(mySegmentsSyncTask.execute());
|
|
101
103
|
});
|
|
@@ -1,36 +1,38 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { definitionsSyncTaskFactory } from './syncTasks/definitionsSyncTask';
|
|
2
2
|
import { segmentsSyncTaskFactory } from './syncTasks/segmentsSyncTask';
|
|
3
|
-
import { IPollingManager, ISegmentsSyncTask,
|
|
3
|
+
import { IPollingManager, ISegmentsSyncTask, IDefinitionsSyncTask } from './types';
|
|
4
4
|
import { POLLING_START, POLLING_STOP, LOG_PREFIX_SYNC_POLLING } from '../../logger/constants';
|
|
5
5
|
import { ISdkFactoryContextSync } from '../../sdkFactory/types';
|
|
6
|
+
import { IDefinitionChangesFetcher } from './fetchers/types';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Expose start / stop mechanism for pulling data from services.
|
|
9
10
|
*/
|
|
10
11
|
export function pollingManagerSSFactory(
|
|
11
|
-
params: ISdkFactoryContextSync
|
|
12
|
+
params: ISdkFactoryContextSync,
|
|
13
|
+
definitionChangesFetcher: IDefinitionChangesFetcher
|
|
12
14
|
): IPollingManager {
|
|
13
15
|
|
|
14
16
|
const { splitApi, storage, readiness, settings } = params;
|
|
15
17
|
const log = settings.log;
|
|
16
18
|
|
|
17
|
-
const
|
|
19
|
+
const definitionsSyncTask: IDefinitionsSyncTask = definitionsSyncTaskFactory(definitionChangesFetcher, storage, readiness, settings);
|
|
18
20
|
const segmentsSyncTask: ISegmentsSyncTask = segmentsSyncTaskFactory(splitApi.fetchSegmentChanges, storage, readiness, settings);
|
|
19
21
|
|
|
20
22
|
return {
|
|
21
|
-
|
|
23
|
+
definitionsSyncTask,
|
|
22
24
|
segmentsSyncTask,
|
|
23
25
|
|
|
24
26
|
// Start periodic fetching (polling)
|
|
25
27
|
start() {
|
|
26
28
|
log.info(POLLING_START);
|
|
27
|
-
log.debug(LOG_PREFIX_SYNC_POLLING +
|
|
28
|
-
log.debug(LOG_PREFIX_SYNC_POLLING + `
|
|
29
|
+
log.debug(LOG_PREFIX_SYNC_POLLING + `${definitionChangesFetcher.type} will be refreshed each ${settings.scheduler.featuresRefreshRate} millis`);
|
|
30
|
+
log.debug(LOG_PREFIX_SYNC_POLLING + `segments will be refreshed each ${settings.scheduler.segmentsRefreshRate} millis`);
|
|
29
31
|
|
|
30
|
-
const startingUp =
|
|
32
|
+
const startingUp = definitionsSyncTask.start();
|
|
31
33
|
if (startingUp) {
|
|
32
34
|
startingUp.then(() => {
|
|
33
|
-
if (
|
|
35
|
+
if (definitionsSyncTask.isRunning()) segmentsSyncTask.start();
|
|
34
36
|
});
|
|
35
37
|
}
|
|
36
38
|
},
|
|
@@ -39,16 +41,16 @@ export function pollingManagerSSFactory(
|
|
|
39
41
|
stop() {
|
|
40
42
|
log.info(POLLING_STOP);
|
|
41
43
|
|
|
42
|
-
if (
|
|
44
|
+
if (definitionsSyncTask.isRunning()) definitionsSyncTask.stop();
|
|
43
45
|
if (segmentsSyncTask.isRunning()) segmentsSyncTask.stop();
|
|
44
46
|
},
|
|
45
47
|
|
|
46
48
|
// Used by SyncManager to know if running in polling mode.
|
|
47
|
-
isRunning:
|
|
49
|
+
isRunning: definitionsSyncTask.isRunning,
|
|
48
50
|
|
|
49
51
|
syncAll() {
|
|
50
|
-
// fetch
|
|
51
|
-
return
|
|
52
|
+
// fetch definitions and segments. There is no need to catch this promise (`DefinitionChangesUpdater` is always resolved with a boolean value)
|
|
53
|
+
return definitionsSyncTask.execute().then(() => {
|
|
52
54
|
return segmentsSyncTask.execute();
|
|
53
55
|
});
|
|
54
56
|
}
|
|
@@ -1,27 +1,26 @@
|
|
|
1
1
|
import { IStorageSync } from '../../../storages/types';
|
|
2
2
|
import { IReadinessManager } from '../../../readiness/types';
|
|
3
3
|
import { syncTaskFactory } from '../../syncTask';
|
|
4
|
-
import {
|
|
5
|
-
import { splitChangesFetcherFactory } from '../fetchers/splitChangesFetcher';
|
|
6
|
-
import { IFetchSplitChanges } from '../../../services/types';
|
|
4
|
+
import { IDefinitionsSyncTask } from '../types';
|
|
7
5
|
import { ISettings } from '../../../types';
|
|
8
|
-
import {
|
|
6
|
+
import { definitionChangesUpdaterFactory } from '../updaters/definitionChangesUpdater';
|
|
7
|
+
import { IDefinitionChangesFetcher } from '../fetchers/types';
|
|
9
8
|
|
|
10
9
|
/**
|
|
11
|
-
* Creates a sync task that periodically executes a `
|
|
10
|
+
* Creates a sync task that periodically executes a `definitionChangesUpdater` task
|
|
12
11
|
*/
|
|
13
|
-
export function
|
|
14
|
-
|
|
12
|
+
export function definitionsSyncTaskFactory(
|
|
13
|
+
definitionChangesFetcher: IDefinitionChangesFetcher,
|
|
15
14
|
storage: IStorageSync,
|
|
16
15
|
readiness: IReadinessManager,
|
|
17
16
|
settings: ISettings,
|
|
18
17
|
isClientSide?: boolean
|
|
19
|
-
):
|
|
18
|
+
): IDefinitionsSyncTask {
|
|
20
19
|
return syncTaskFactory(
|
|
21
20
|
settings.log,
|
|
22
|
-
|
|
21
|
+
definitionChangesUpdaterFactory(
|
|
23
22
|
settings.log,
|
|
24
|
-
|
|
23
|
+
definitionChangesFetcher,
|
|
25
24
|
storage,
|
|
26
25
|
settings.sync.__splitFiltersValidation,
|
|
27
26
|
readiness.splits,
|
|
@@ -30,6 +29,6 @@ export function splitsSyncTaskFactory(
|
|
|
30
29
|
isClientSide
|
|
31
30
|
),
|
|
32
31
|
settings.scheduler.featuresRefreshRate,
|
|
33
|
-
'
|
|
32
|
+
'definitionChangesUpdater',
|
|
34
33
|
);
|
|
35
34
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { IRBSegment,
|
|
1
|
+
import { IRBSegment, IDefinition } from '../../dtos/types';
|
|
2
2
|
import { IReadinessManager } from '../../readiness/types';
|
|
3
3
|
import { IStorageSync } from '../../storages/types';
|
|
4
4
|
import { MEMBERSHIPS_LS_UPDATE, MEMBERSHIPS_MS_UPDATE } from '../streaming/types';
|
|
5
5
|
import { ITask, ISyncTask } from '../types';
|
|
6
6
|
|
|
7
|
-
export interface
|
|
7
|
+
export interface IDefinitionsSyncTask extends ISyncTask<[noCache?: boolean, till?: number, splitUpdateNotification?: { payload: IDefinition | IRBSegment, changeNumber: number }], boolean> { }
|
|
8
8
|
|
|
9
9
|
export interface ISegmentsSyncTask extends ISyncTask<[fetchOnlyNew?: boolean, segmentName?: string, noCache?: boolean, till?: number], boolean> { }
|
|
10
10
|
|
|
@@ -19,7 +19,7 @@ export interface IMySegmentsSyncTask extends ISyncTask<[segmentsData?: MySegment
|
|
|
19
19
|
|
|
20
20
|
export interface IPollingManager extends ITask {
|
|
21
21
|
syncAll(): Promise<any>
|
|
22
|
-
|
|
22
|
+
definitionsSyncTask: IDefinitionsSyncTask
|
|
23
23
|
segmentsSyncTask: ISyncTask
|
|
24
24
|
}
|
|
25
25
|
|