@splitsoftware/splitio-commons 2.2.1-rc.5 → 2.3.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 +26 -26
- package/README.md +0 -1
- package/cjs/evaluator/combiners/and.js +6 -2
- package/cjs/evaluator/combiners/ifelseif.js +6 -6
- package/cjs/evaluator/condition/index.js +5 -6
- package/cjs/evaluator/index.js +7 -7
- package/cjs/evaluator/matchers/index.js +1 -3
- package/cjs/evaluator/matchers/matcherTypes.js +0 -1
- package/cjs/evaluator/matchersTransform/index.js +0 -4
- package/cjs/evaluator/parser/index.js +2 -2
- package/cjs/evaluator/value/sanitize.js +0 -1
- package/cjs/logger/constants.js +3 -4
- package/cjs/logger/messages/debug.js +2 -3
- package/cjs/logger/messages/warn.js +1 -1
- package/cjs/services/splitApi.js +4 -3
- package/cjs/services/splitHttpClient.js +3 -2
- package/cjs/storages/AbstractSplitsCacheSync.js +2 -5
- package/cjs/storages/KeyBuilder.js +0 -9
- package/cjs/storages/KeyBuilderCS.js +0 -3
- package/cjs/storages/KeyBuilderSS.js +0 -3
- package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +14 -9
- package/cjs/storages/inLocalStorage/index.js +1 -5
- package/cjs/storages/inLocalStorage/validateCache.js +1 -2
- package/cjs/storages/inMemory/InMemoryStorage.js +0 -3
- package/cjs/storages/inMemory/InMemoryStorageCS.js +0 -4
- package/cjs/storages/inMemory/SplitsCacheInMemory.js +0 -1
- package/cjs/storages/inRedis/index.js +0 -2
- package/cjs/storages/pluggable/index.js +0 -2
- package/cjs/sync/polling/fetchers/splitChangesFetcher.js +4 -54
- package/cjs/sync/polling/pollingManagerCS.js +7 -7
- package/cjs/sync/polling/syncTasks/splitsSyncTask.js +1 -1
- package/cjs/sync/polling/updaters/mySegmentsUpdater.js +2 -2
- package/cjs/sync/polling/updaters/segmentChangesUpdater.js +1 -1
- package/cjs/sync/polling/updaters/splitChangesUpdater.js +33 -59
- package/cjs/sync/streaming/SSEHandler/index.js +0 -1
- package/cjs/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +77 -106
- package/cjs/sync/streaming/constants.js +1 -2
- package/cjs/sync/streaming/pushManager.js +16 -3
- package/cjs/sync/syncManagerOnline.js +2 -2
- package/cjs/utils/constants/index.js +2 -6
- package/esm/evaluator/combiners/and.js +6 -2
- package/esm/evaluator/combiners/ifelseif.js +7 -7
- package/esm/evaluator/condition/index.js +5 -6
- package/esm/evaluator/index.js +7 -7
- package/esm/evaluator/matchers/index.js +1 -3
- package/esm/evaluator/matchers/matcherTypes.js +0 -1
- package/esm/evaluator/matchersTransform/index.js +0 -4
- package/esm/evaluator/parser/index.js +2 -2
- package/esm/evaluator/value/sanitize.js +0 -1
- package/esm/logger/constants.js +0 -1
- package/esm/logger/messages/debug.js +2 -3
- package/esm/logger/messages/warn.js +1 -1
- package/esm/services/splitApi.js +4 -3
- package/esm/services/splitHttpClient.js +3 -2
- package/esm/storages/AbstractSplitsCacheSync.js +2 -5
- package/esm/storages/KeyBuilder.js +0 -9
- package/esm/storages/KeyBuilderCS.js +0 -3
- package/esm/storages/KeyBuilderSS.js +0 -3
- package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +14 -9
- package/esm/storages/inLocalStorage/index.js +1 -5
- package/esm/storages/inLocalStorage/validateCache.js +1 -2
- package/esm/storages/inMemory/InMemoryStorage.js +0 -3
- package/esm/storages/inMemory/InMemoryStorageCS.js +0 -4
- package/esm/storages/inMemory/SplitsCacheInMemory.js +0 -1
- package/esm/storages/inRedis/index.js +0 -2
- package/esm/storages/pluggable/index.js +0 -2
- package/esm/sync/polling/fetchers/splitChangesFetcher.js +4 -54
- package/esm/sync/polling/pollingManagerCS.js +7 -7
- package/esm/sync/polling/syncTasks/splitsSyncTask.js +1 -1
- package/esm/sync/polling/updaters/mySegmentsUpdater.js +2 -2
- package/esm/sync/polling/updaters/segmentChangesUpdater.js +1 -1
- package/esm/sync/polling/updaters/splitChangesUpdater.js +33 -59
- package/esm/sync/streaming/SSEHandler/index.js +1 -2
- package/esm/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +73 -102
- package/esm/sync/streaming/constants.js +0 -1
- package/esm/sync/streaming/pushManager.js +19 -6
- package/esm/sync/syncManagerOnline.js +2 -2
- package/esm/utils/constants/index.js +1 -5
- package/package.json +1 -1
- package/src/dtos/types.ts +8 -37
- package/src/evaluator/Engine.ts +1 -1
- package/src/evaluator/combiners/and.ts +4 -5
- package/src/evaluator/combiners/ifelseif.ts +9 -7
- package/src/evaluator/condition/engineUtils.ts +1 -1
- package/src/evaluator/condition/index.ts +12 -12
- package/src/evaluator/index.ts +7 -7
- package/src/evaluator/matchers/index.ts +1 -3
- package/src/evaluator/matchers/matcherTypes.ts +0 -1
- package/src/evaluator/matchersTransform/index.ts +0 -3
- package/src/evaluator/parser/index.ts +3 -3
- package/src/evaluator/types.ts +2 -2
- package/src/evaluator/value/index.ts +2 -2
- package/src/evaluator/value/sanitize.ts +4 -5
- package/src/logger/constants.ts +0 -1
- package/src/logger/messages/debug.ts +2 -3
- package/src/logger/messages/warn.ts +1 -1
- package/src/sdkFactory/types.ts +1 -1
- package/src/sdkManager/index.ts +1 -1
- package/src/services/splitApi.ts +4 -3
- package/src/services/splitHttpClient.ts +3 -2
- package/src/services/types.ts +1 -1
- package/src/storages/AbstractSplitsCacheSync.ts +3 -6
- package/src/storages/KeyBuilder.ts +0 -12
- package/src/storages/KeyBuilderCS.ts +0 -4
- package/src/storages/KeyBuilderSS.ts +0 -4
- package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +14 -10
- package/src/storages/inLocalStorage/index.ts +1 -5
- package/src/storages/inLocalStorage/validateCache.ts +1 -3
- package/src/storages/inMemory/InMemoryStorage.ts +0 -3
- package/src/storages/inMemory/InMemoryStorageCS.ts +0 -4
- package/src/storages/inMemory/SplitsCacheInMemory.ts +0 -1
- package/src/storages/inRedis/index.ts +0 -2
- package/src/storages/pluggable/index.ts +0 -2
- package/src/storages/types.ts +1 -33
- package/src/sync/polling/fetchers/splitChangesFetcher.ts +4 -65
- package/src/sync/polling/fetchers/types.ts +0 -1
- package/src/sync/polling/pollingManagerCS.ts +7 -7
- package/src/sync/polling/syncTasks/splitsSyncTask.ts +1 -1
- package/src/sync/polling/types.ts +2 -2
- package/src/sync/polling/updaters/mySegmentsUpdater.ts +2 -2
- package/src/sync/polling/updaters/segmentChangesUpdater.ts +1 -1
- package/src/sync/polling/updaters/splitChangesUpdater.ts +43 -70
- package/src/sync/streaming/SSEHandler/index.ts +1 -2
- package/src/sync/streaming/SSEHandler/types.ts +2 -2
- package/src/sync/streaming/UpdateWorkers/SplitsUpdateWorker.ts +68 -98
- package/src/sync/streaming/constants.ts +0 -1
- package/src/sync/streaming/parseUtils.ts +2 -2
- package/src/sync/streaming/pushManager.ts +18 -6
- package/src/sync/streaming/types.ts +2 -3
- package/src/sync/syncManagerOnline.ts +2 -2
- package/src/utils/constants/index.ts +1 -6
- package/src/utils/lang/index.ts +1 -1
- package/cjs/evaluator/matchers/rbsegment.js +0 -56
- package/cjs/storages/inLocalStorage/RBSegmentsCacheInLocal.js +0 -117
- package/cjs/storages/inMemory/RBSegmentsCacheInMemory.js +0 -61
- package/cjs/storages/inRedis/RBSegmentsCacheInRedis.js +0 -64
- package/cjs/storages/pluggable/RBSegmentsCachePluggable.js +0 -64
- package/esm/evaluator/matchers/rbsegment.js +0 -52
- package/esm/storages/inLocalStorage/RBSegmentsCacheInLocal.js +0 -114
- package/esm/storages/inMemory/RBSegmentsCacheInMemory.js +0 -58
- package/esm/storages/inRedis/RBSegmentsCacheInRedis.js +0 -61
- package/esm/storages/pluggable/RBSegmentsCachePluggable.js +0 -61
- package/src/evaluator/matchers/rbsegment.ts +0 -74
- package/src/storages/inLocalStorage/RBSegmentsCacheInLocal.ts +0 -136
- package/src/storages/inMemory/RBSegmentsCacheInMemory.ts +0 -68
- package/src/storages/inRedis/RBSegmentsCacheInRedis.ts +0 -79
- package/src/storages/pluggable/RBSegmentsCachePluggable.ts +0 -76
|
@@ -47,14 +47,16 @@ export class SplitsCacheInLocal extends AbstractSplitsCacheSync {
|
|
|
47
47
|
|
|
48
48
|
private _incrementCounts(split: ISplit) {
|
|
49
49
|
try {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
localStorage.setItem(ttKey, toNumber(localStorage.getItem(ttKey)) + 1);
|
|
53
|
-
|
|
54
|
-
if (usesSegments(split)) {
|
|
55
|
-
const segmentsCountKey = this.keys.buildSplitsWithSegmentCountKey();
|
|
50
|
+
if (split) {
|
|
51
|
+
const ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
|
|
56
52
|
// @ts-expect-error
|
|
57
|
-
localStorage.setItem(
|
|
53
|
+
localStorage.setItem(ttKey, toNumber(localStorage.getItem(ttKey)) + 1);
|
|
54
|
+
|
|
55
|
+
if (usesSegments(split)) {
|
|
56
|
+
const segmentsCountKey = this.keys.buildSplitsWithSegmentCountKey();
|
|
57
|
+
// @ts-expect-error
|
|
58
|
+
localStorage.setItem(segmentsCountKey, toNumber(localStorage.getItem(segmentsCountKey)) + 1);
|
|
59
|
+
}
|
|
58
60
|
}
|
|
59
61
|
} catch (e) {
|
|
60
62
|
this.log.error(LOG_PREFIX + e);
|
|
@@ -183,9 +185,11 @@ export class SplitsCacheInLocal extends AbstractSplitsCacheSync {
|
|
|
183
185
|
const storedCount = localStorage.getItem(this.keys.buildSplitsWithSegmentCountKey());
|
|
184
186
|
const splitsWithSegmentsCount = storedCount === null ? 0 : toNumber(storedCount);
|
|
185
187
|
|
|
186
|
-
|
|
187
|
-
splitsWithSegmentsCount > 0
|
|
188
|
-
|
|
188
|
+
if (isFiniteNumber(splitsWithSegmentsCount)) {
|
|
189
|
+
return splitsWithSegmentsCount > 0;
|
|
190
|
+
} else {
|
|
191
|
+
return true;
|
|
192
|
+
}
|
|
189
193
|
}
|
|
190
194
|
|
|
191
195
|
getNamesByFlagSets(flagSets: string[]): Set<string>[] {
|
|
@@ -6,7 +6,6 @@ import { validatePrefix } from '../KeyBuilder';
|
|
|
6
6
|
import { KeyBuilderCS, myLargeSegmentsKeyBuilder } from '../KeyBuilderCS';
|
|
7
7
|
import { isLocalStorageAvailable } from '../../utils/env/isLocalStorageAvailable';
|
|
8
8
|
import { SplitsCacheInLocal } from './SplitsCacheInLocal';
|
|
9
|
-
import { RBSegmentsCacheInLocal } from './RBSegmentsCacheInLocal';
|
|
10
9
|
import { MySegmentsCacheInLocal } from './MySegmentsCacheInLocal';
|
|
11
10
|
import { InMemoryStorageCSFactory } from '../inMemory/InMemoryStorageCS';
|
|
12
11
|
import { LOG_PREFIX } from './constants';
|
|
@@ -37,13 +36,11 @@ export function InLocalStorage(options: SplitIO.InLocalStorageOptions = {}): ISt
|
|
|
37
36
|
const keys = new KeyBuilderCS(prefix, matchingKey);
|
|
38
37
|
|
|
39
38
|
const splits = new SplitsCacheInLocal(settings, keys);
|
|
40
|
-
const rbSegments = new RBSegmentsCacheInLocal(settings, keys);
|
|
41
39
|
const segments = new MySegmentsCacheInLocal(log, keys);
|
|
42
40
|
const largeSegments = new MySegmentsCacheInLocal(log, myLargeSegmentsKeyBuilder(prefix, matchingKey));
|
|
43
41
|
|
|
44
42
|
return {
|
|
45
43
|
splits,
|
|
46
|
-
rbSegments,
|
|
47
44
|
segments,
|
|
48
45
|
largeSegments,
|
|
49
46
|
impressions: new ImpressionsCacheInMemory(impressionsQueueSize),
|
|
@@ -53,7 +50,7 @@ export function InLocalStorage(options: SplitIO.InLocalStorageOptions = {}): ISt
|
|
|
53
50
|
uniqueKeys: new UniqueKeysCacheInMemoryCS(),
|
|
54
51
|
|
|
55
52
|
validateCache() {
|
|
56
|
-
return validateCache(options, settings, keys, splits,
|
|
53
|
+
return validateCache(options, settings, keys, splits, segments, largeSegments);
|
|
57
54
|
},
|
|
58
55
|
|
|
59
56
|
destroy() { },
|
|
@@ -63,7 +60,6 @@ export function InLocalStorage(options: SplitIO.InLocalStorageOptions = {}): ISt
|
|
|
63
60
|
|
|
64
61
|
return {
|
|
65
62
|
splits: this.splits,
|
|
66
|
-
rbSegments: this.rbSegments,
|
|
67
63
|
segments: new MySegmentsCacheInLocal(log, new KeyBuilderCS(prefix, matchingKey)),
|
|
68
64
|
largeSegments: new MySegmentsCacheInLocal(log, myLargeSegmentsKeyBuilder(prefix, matchingKey)),
|
|
69
65
|
impressions: this.impressions,
|
|
@@ -3,7 +3,6 @@ import { isFiniteNumber, isNaNNumber } from '../../utils/lang';
|
|
|
3
3
|
import { getStorageHash } from '../KeyBuilder';
|
|
4
4
|
import { LOG_PREFIX } from './constants';
|
|
5
5
|
import type { SplitsCacheInLocal } from './SplitsCacheInLocal';
|
|
6
|
-
import type { RBSegmentsCacheInLocal } from './RBSegmentsCacheInLocal';
|
|
7
6
|
import type { MySegmentsCacheInLocal } from './MySegmentsCacheInLocal';
|
|
8
7
|
import { KeyBuilderCS } from '../KeyBuilderCS';
|
|
9
8
|
import SplitIO from '../../../types/splitio';
|
|
@@ -67,14 +66,13 @@ function validateExpiration(options: SplitIO.InLocalStorageOptions, settings: IS
|
|
|
67
66
|
*
|
|
68
67
|
* @returns `true` if cache is ready to be used, `false` otherwise (cache was cleared or there is no cache)
|
|
69
68
|
*/
|
|
70
|
-
export function validateCache(options: SplitIO.InLocalStorageOptions, settings: ISettings, keys: KeyBuilderCS, splits: SplitsCacheInLocal,
|
|
69
|
+
export function validateCache(options: SplitIO.InLocalStorageOptions, settings: ISettings, keys: KeyBuilderCS, splits: SplitsCacheInLocal, segments: MySegmentsCacheInLocal, largeSegments: MySegmentsCacheInLocal): boolean {
|
|
71
70
|
|
|
72
71
|
const currentTimestamp = Date.now();
|
|
73
72
|
const isThereCache = splits.getChangeNumber() > -1;
|
|
74
73
|
|
|
75
74
|
if (validateExpiration(options, settings, keys, currentTimestamp, isThereCache)) {
|
|
76
75
|
splits.clear();
|
|
77
|
-
rbSegments.clear();
|
|
78
76
|
segments.clear();
|
|
79
77
|
largeSegments.clear();
|
|
80
78
|
|
|
@@ -7,7 +7,6 @@ import { ImpressionCountsCacheInMemory } from './ImpressionCountsCacheInMemory';
|
|
|
7
7
|
import { LOCALHOST_MODE, STORAGE_MEMORY } from '../../utils/constants';
|
|
8
8
|
import { shouldRecordTelemetry, TelemetryCacheInMemory } from './TelemetryCacheInMemory';
|
|
9
9
|
import { UniqueKeysCacheInMemory } from './UniqueKeysCacheInMemory';
|
|
10
|
-
import { RBSegmentsCacheInMemory } from './RBSegmentsCacheInMemory';
|
|
11
10
|
|
|
12
11
|
/**
|
|
13
12
|
* InMemory storage factory for standalone server-side SplitFactory
|
|
@@ -18,12 +17,10 @@ export function InMemoryStorageFactory(params: IStorageFactoryParams): IStorageS
|
|
|
18
17
|
const { settings: { scheduler: { impressionsQueueSize, eventsQueueSize, }, sync: { __splitFiltersValidation } } } = params;
|
|
19
18
|
|
|
20
19
|
const splits = new SplitsCacheInMemory(__splitFiltersValidation);
|
|
21
|
-
const rbSegments = new RBSegmentsCacheInMemory();
|
|
22
20
|
const segments = new SegmentsCacheInMemory();
|
|
23
21
|
|
|
24
22
|
const storage = {
|
|
25
23
|
splits,
|
|
26
|
-
rbSegments,
|
|
27
24
|
segments,
|
|
28
25
|
impressions: new ImpressionsCacheInMemory(impressionsQueueSize),
|
|
29
26
|
impressionCounts: new ImpressionCountsCacheInMemory(),
|
|
@@ -7,7 +7,6 @@ import { ImpressionCountsCacheInMemory } from './ImpressionCountsCacheInMemory';
|
|
|
7
7
|
import { LOCALHOST_MODE, STORAGE_MEMORY } from '../../utils/constants';
|
|
8
8
|
import { shouldRecordTelemetry, TelemetryCacheInMemory } from './TelemetryCacheInMemory';
|
|
9
9
|
import { UniqueKeysCacheInMemoryCS } from './UniqueKeysCacheInMemoryCS';
|
|
10
|
-
import { RBSegmentsCacheInMemory } from './RBSegmentsCacheInMemory';
|
|
11
10
|
|
|
12
11
|
/**
|
|
13
12
|
* InMemory storage factory for standalone client-side SplitFactory
|
|
@@ -18,13 +17,11 @@ export function InMemoryStorageCSFactory(params: IStorageFactoryParams): IStorag
|
|
|
18
17
|
const { settings: { scheduler: { impressionsQueueSize, eventsQueueSize }, sync: { __splitFiltersValidation } } } = params;
|
|
19
18
|
|
|
20
19
|
const splits = new SplitsCacheInMemory(__splitFiltersValidation);
|
|
21
|
-
const rbSegments = new RBSegmentsCacheInMemory();
|
|
22
20
|
const segments = new MySegmentsCacheInMemory();
|
|
23
21
|
const largeSegments = new MySegmentsCacheInMemory();
|
|
24
22
|
|
|
25
23
|
const storage = {
|
|
26
24
|
splits,
|
|
27
|
-
rbSegments,
|
|
28
25
|
segments,
|
|
29
26
|
largeSegments,
|
|
30
27
|
impressions: new ImpressionsCacheInMemory(impressionsQueueSize),
|
|
@@ -39,7 +36,6 @@ export function InMemoryStorageCSFactory(params: IStorageFactoryParams): IStorag
|
|
|
39
36
|
shared() {
|
|
40
37
|
return {
|
|
41
38
|
splits: this.splits,
|
|
42
|
-
rbSegments: this.rbSegments,
|
|
43
39
|
segments: new MySegmentsCacheInMemory(),
|
|
44
40
|
largeSegments: new MySegmentsCacheInMemory(),
|
|
45
41
|
impressions: this.impressions,
|
|
@@ -11,7 +11,6 @@ import { TelemetryCacheInRedis } from './TelemetryCacheInRedis';
|
|
|
11
11
|
import { UniqueKeysCacheInRedis } from './UniqueKeysCacheInRedis';
|
|
12
12
|
import { ImpressionCountsCacheInRedis } from './ImpressionCountsCacheInRedis';
|
|
13
13
|
import { metadataBuilder } from '../utils';
|
|
14
|
-
import { RBSegmentsCacheInRedis } from './RBSegmentsCacheInRedis';
|
|
15
14
|
|
|
16
15
|
export interface InRedisStorageOptions {
|
|
17
16
|
prefix?: string
|
|
@@ -60,7 +59,6 @@ export function InRedisStorage(options: InRedisStorageOptions = {}): IStorageAsy
|
|
|
60
59
|
|
|
61
60
|
return {
|
|
62
61
|
splits: new SplitsCacheInRedis(log, keys, redisClient, settings.sync.__splitFiltersValidation),
|
|
63
|
-
rbSegments: new RBSegmentsCacheInRedis(log, keys, redisClient),
|
|
64
62
|
segments: new SegmentsCacheInRedis(log, keys, redisClient),
|
|
65
63
|
impressions: new ImpressionsCacheInRedis(log, keys.buildImpressionsKey(), redisClient, metadata),
|
|
66
64
|
impressionCounts: impressionCountsCache,
|
|
@@ -20,7 +20,6 @@ import { UniqueKeysCacheInMemory } from '../inMemory/UniqueKeysCacheInMemory';
|
|
|
20
20
|
import { UniqueKeysCacheInMemoryCS } from '../inMemory/UniqueKeysCacheInMemoryCS';
|
|
21
21
|
import { metadataBuilder } from '../utils';
|
|
22
22
|
import { LOG_PREFIX } from '../pluggable/constants';
|
|
23
|
-
import { RBSegmentsCachePluggable } from './RBSegmentsCachePluggable';
|
|
24
23
|
|
|
25
24
|
const NO_VALID_WRAPPER = 'Expecting pluggable storage `wrapper` in options, but no valid wrapper instance was provided.';
|
|
26
25
|
const NO_VALID_WRAPPER_INTERFACE = 'The provided wrapper instance doesn’t follow the expected interface. Check our docs.';
|
|
@@ -118,7 +117,6 @@ export function PluggableStorage(options: PluggableStorageOptions): IStorageAsyn
|
|
|
118
117
|
|
|
119
118
|
return {
|
|
120
119
|
splits: new SplitsCachePluggable(log, keys, wrapper, settings.sync.__splitFiltersValidation),
|
|
121
|
-
rbSegments: new RBSegmentsCachePluggable(log, keys, wrapper),
|
|
122
120
|
segments: new SegmentsCachePluggable(log, keys, wrapper),
|
|
123
121
|
impressions: isPartialConsumer ? new ImpressionsCacheInMemory(impressionsQueueSize) : new ImpressionsCachePluggable(log, keys.buildImpressionsKey(), wrapper, metadata),
|
|
124
122
|
impressionCounts: impressionCountsCache,
|
package/src/storages/types.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import SplitIO from '../../types/splitio';
|
|
2
|
-
import { MaybeThenable, ISplit,
|
|
2
|
+
import { MaybeThenable, ISplit, IMySegmentsResponse } from '../dtos/types';
|
|
3
3
|
import { MySegmentsData } from '../sync/polling/types';
|
|
4
4
|
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
5
|
import { ISettings } from '../types';
|
|
@@ -221,34 +221,6 @@ export interface ISplitsCacheAsync extends ISplitsCacheBase {
|
|
|
221
221
|
getNamesByFlagSets(flagSets: string[]): Promise<Set<string>[]>
|
|
222
222
|
}
|
|
223
223
|
|
|
224
|
-
/** Rule-Based Segments cache */
|
|
225
|
-
|
|
226
|
-
export interface IRBSegmentsCacheBase {
|
|
227
|
-
update(toAdd: IRBSegment[], toRemove: IRBSegment[], changeNumber: number): MaybeThenable<boolean>,
|
|
228
|
-
get(name: string): MaybeThenable<IRBSegment | null>,
|
|
229
|
-
getChangeNumber(): MaybeThenable<number>,
|
|
230
|
-
clear(): MaybeThenable<boolean | void>,
|
|
231
|
-
contains(names: Set<string>): MaybeThenable<boolean>,
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
export interface IRBSegmentsCacheSync extends IRBSegmentsCacheBase {
|
|
235
|
-
update(toAdd: IRBSegment[], toRemove: IRBSegment[], changeNumber: number): boolean,
|
|
236
|
-
get(name: string): IRBSegment | null,
|
|
237
|
-
getChangeNumber(): number,
|
|
238
|
-
clear(): void,
|
|
239
|
-
contains(names: Set<string>): boolean,
|
|
240
|
-
// Used only for smart pausing in client-side standalone. Returns true if the storage contains a RBSegment using segments or large segments matchers
|
|
241
|
-
usesSegments(): boolean,
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
export interface IRBSegmentsCacheAsync extends IRBSegmentsCacheBase {
|
|
245
|
-
update(toAdd: IRBSegment[], toRemove: IRBSegment[], changeNumber: number): Promise<boolean>,
|
|
246
|
-
get(name: string): Promise<IRBSegment | null>,
|
|
247
|
-
getChangeNumber(): Promise<number>,
|
|
248
|
-
clear(): Promise<boolean | void>,
|
|
249
|
-
contains(names: Set<string>): Promise<boolean>,
|
|
250
|
-
}
|
|
251
|
-
|
|
252
224
|
/** Segments cache */
|
|
253
225
|
|
|
254
226
|
export interface ISegmentsCacheBase {
|
|
@@ -447,7 +419,6 @@ export interface ITelemetryCacheAsync extends ITelemetryEvaluationProducerAsync,
|
|
|
447
419
|
|
|
448
420
|
export interface IStorageBase<
|
|
449
421
|
TSplitsCache extends ISplitsCacheBase = ISplitsCacheBase,
|
|
450
|
-
TRBSegmentsCache extends IRBSegmentsCacheBase = IRBSegmentsCacheBase,
|
|
451
422
|
TSegmentsCache extends ISegmentsCacheBase = ISegmentsCacheBase,
|
|
452
423
|
TImpressionsCache extends IImpressionsCacheBase = IImpressionsCacheBase,
|
|
453
424
|
TImpressionsCountCache extends IImpressionCountsCacheBase = IImpressionCountsCacheBase,
|
|
@@ -456,7 +427,6 @@ export interface IStorageBase<
|
|
|
456
427
|
TUniqueKeysCache extends IUniqueKeysCacheBase = IUniqueKeysCacheBase
|
|
457
428
|
> {
|
|
458
429
|
splits: TSplitsCache,
|
|
459
|
-
rbSegments: TRBSegmentsCache,
|
|
460
430
|
segments: TSegmentsCache,
|
|
461
431
|
impressions: TImpressionsCache,
|
|
462
432
|
impressionCounts: TImpressionsCountCache,
|
|
@@ -469,7 +439,6 @@ export interface IStorageBase<
|
|
|
469
439
|
|
|
470
440
|
export interface IStorageSync extends IStorageBase<
|
|
471
441
|
ISplitsCacheSync,
|
|
472
|
-
IRBSegmentsCacheSync,
|
|
473
442
|
ISegmentsCacheSync,
|
|
474
443
|
IImpressionsCacheSync,
|
|
475
444
|
IImpressionCountsCacheSync,
|
|
@@ -484,7 +453,6 @@ export interface IStorageSync extends IStorageBase<
|
|
|
484
453
|
|
|
485
454
|
export interface IStorageAsync extends IStorageBase<
|
|
486
455
|
ISplitsCacheAsync,
|
|
487
|
-
IRBSegmentsCacheAsync,
|
|
488
456
|
ISegmentsCacheAsync,
|
|
489
457
|
IImpressionsCacheAsync | IImpressionsCacheSync,
|
|
490
458
|
IImpressionCountsCacheBase,
|
|
@@ -1,85 +1,24 @@
|
|
|
1
|
-
import { ISettings } from '../../../types';
|
|
2
|
-
import { ISplitChangesResponse } from '../../../dtos/types';
|
|
3
1
|
import { IFetchSplitChanges, IResponse } from '../../../services/types';
|
|
4
|
-
import { IStorageBase } from '../../../storages/types';
|
|
5
|
-
import { FLAG_SPEC_VERSION } from '../../../utils/constants';
|
|
6
|
-
import { base } from '../../../utils/settingsValidation';
|
|
7
2
|
import { ISplitChangesFetcher } from './types';
|
|
8
|
-
import { LOG_PREFIX_SYNC_SPLITS } from '../../../logger/constants';
|
|
9
|
-
|
|
10
|
-
const PROXY_CHECK_INTERVAL_MILLIS_CS = 60 * 60 * 1000; // 1 hour in Client Side
|
|
11
|
-
const PROXY_CHECK_INTERVAL_MILLIS_SS = 24 * PROXY_CHECK_INTERVAL_MILLIS_CS; // 24 hours in Server Side
|
|
12
|
-
|
|
13
|
-
function sdkEndpointOverridden(settings: ISettings) {
|
|
14
|
-
return settings.urls.sdk !== base.urls.sdk;
|
|
15
|
-
}
|
|
16
3
|
|
|
17
4
|
/**
|
|
18
5
|
* Factory of SplitChanges fetcher.
|
|
19
6
|
* SplitChanges fetcher is a wrapper around `splitChanges` API service that parses the response and handle errors.
|
|
20
7
|
*/
|
|
21
|
-
|
|
22
|
-
export function splitChangesFetcherFactory(fetchSplitChanges: IFetchSplitChanges, settings: ISettings, storage: Pick<IStorageBase, 'splits' | 'rbSegments'>): ISplitChangesFetcher {
|
|
23
|
-
|
|
24
|
-
const log = settings.log;
|
|
25
|
-
const PROXY_CHECK_INTERVAL_MILLIS = settings.core.key !== undefined ? PROXY_CHECK_INTERVAL_MILLIS_CS : PROXY_CHECK_INTERVAL_MILLIS_SS;
|
|
26
|
-
let lastProxyCheckTimestamp: number | undefined;
|
|
8
|
+
export function splitChangesFetcherFactory(fetchSplitChanges: IFetchSplitChanges): ISplitChangesFetcher {
|
|
27
9
|
|
|
28
10
|
return function splitChangesFetcher(
|
|
29
11
|
since: number,
|
|
30
12
|
noCache?: boolean,
|
|
31
13
|
till?: number,
|
|
32
|
-
rbSince?: number,
|
|
33
14
|
// Optional decorator for `fetchSplitChanges` promise, such as timeout or time tracker
|
|
34
15
|
decorator?: (promise: Promise<IResponse>) => Promise<IResponse>
|
|
35
|
-
)
|
|
36
|
-
|
|
37
|
-
// Recheck proxy
|
|
38
|
-
if (lastProxyCheckTimestamp && (Date.now() - lastProxyCheckTimestamp) > PROXY_CHECK_INTERVAL_MILLIS) {
|
|
39
|
-
settings.sync.flagSpecVersion = FLAG_SPEC_VERSION;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
let splitsPromise = fetchSplitChanges(since, noCache, till, settings.sync.flagSpecVersion === FLAG_SPEC_VERSION ? rbSince : undefined)
|
|
43
|
-
// Handle proxy error with spec 1.3
|
|
44
|
-
.catch((err) => {
|
|
45
|
-
if (err.statusCode === 400 && sdkEndpointOverridden(settings) && settings.sync.flagSpecVersion === FLAG_SPEC_VERSION) {
|
|
46
|
-
log.error(LOG_PREFIX_SYNC_SPLITS + 'Proxy error detected. Retrying with spec 1.2. If you are using Split Proxy, please upgrade to latest version');
|
|
47
|
-
lastProxyCheckTimestamp = Date.now();
|
|
48
|
-
settings.sync.flagSpecVersion = '1.2'; // fallback to 1.2 spec
|
|
49
|
-
return fetchSplitChanges(since, noCache, till); // retry request without rbSince
|
|
50
|
-
}
|
|
51
|
-
throw err;
|
|
52
|
-
});
|
|
16
|
+
) {
|
|
53
17
|
|
|
18
|
+
let splitsPromise = fetchSplitChanges(since, noCache, till);
|
|
54
19
|
if (decorator) splitsPromise = decorator(splitsPromise);
|
|
55
20
|
|
|
56
|
-
return splitsPromise
|
|
57
|
-
.then(resp => resp.json())
|
|
58
|
-
.then(data => {
|
|
59
|
-
// Using flag spec version 1.2
|
|
60
|
-
if (data.splits) {
|
|
61
|
-
return {
|
|
62
|
-
ff: {
|
|
63
|
-
d: data.splits,
|
|
64
|
-
s: data.since,
|
|
65
|
-
t: data.till
|
|
66
|
-
}
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// Proxy recovery
|
|
71
|
-
if (lastProxyCheckTimestamp) {
|
|
72
|
-
log.info(LOG_PREFIX_SYNC_SPLITS + 'Proxy error recovered');
|
|
73
|
-
lastProxyCheckTimestamp = undefined;
|
|
74
|
-
return splitChangesFetcher(-1, undefined, undefined, -1)
|
|
75
|
-
.then((splitChangesResponse: ISplitChangesResponse) =>
|
|
76
|
-
Promise.all([storage.splits.clear(), storage.rbSegments.clear()])
|
|
77
|
-
.then(() => splitChangesResponse)
|
|
78
|
-
);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
return data;
|
|
82
|
-
});
|
|
21
|
+
return splitsPromise.then(resp => resp.json());
|
|
83
22
|
};
|
|
84
23
|
|
|
85
24
|
}
|
|
@@ -43,10 +43,10 @@ export function pollingManagerCSFactory(
|
|
|
43
43
|
// smart pausing
|
|
44
44
|
readiness.splits.on(SDK_SPLITS_ARRIVED, () => {
|
|
45
45
|
if (!splitsSyncTask.isRunning()) return; // noop if not doing polling
|
|
46
|
-
const
|
|
47
|
-
if (
|
|
48
|
-
log.info(POLLING_SMART_PAUSING, [
|
|
49
|
-
if (
|
|
46
|
+
const splitsHaveSegments = storage.splits.usesSegments();
|
|
47
|
+
if (splitsHaveSegments !== mySegmentsSyncTask.isRunning()) {
|
|
48
|
+
log.info(POLLING_SMART_PAUSING, [splitsHaveSegments ? 'ON' : 'OFF']);
|
|
49
|
+
if (splitsHaveSegments) {
|
|
50
50
|
startMySegmentsSyncTasks();
|
|
51
51
|
} else {
|
|
52
52
|
stopMySegmentsSyncTasks();
|
|
@@ -59,9 +59,9 @@ export function pollingManagerCSFactory(
|
|
|
59
59
|
|
|
60
60
|
// smart ready
|
|
61
61
|
function smartReady() {
|
|
62
|
-
if (!readiness.isReady() && !storage.splits.usesSegments()
|
|
62
|
+
if (!readiness.isReady() && !storage.splits.usesSegments()) readiness.segments.emit(SDK_SEGMENTS_ARRIVED);
|
|
63
63
|
}
|
|
64
|
-
if (!storage.splits.usesSegments()
|
|
64
|
+
if (!storage.splits.usesSegments()) setTimeout(smartReady, 0);
|
|
65
65
|
else readiness.splits.once(SDK_SPLITS_ARRIVED, smartReady);
|
|
66
66
|
|
|
67
67
|
mySegmentsSyncTasks[matchingKey] = mySegmentsSyncTask;
|
|
@@ -77,7 +77,7 @@ export function pollingManagerCSFactory(
|
|
|
77
77
|
log.info(POLLING_START);
|
|
78
78
|
|
|
79
79
|
splitsSyncTask.start();
|
|
80
|
-
if (storage.splits.usesSegments()
|
|
80
|
+
if (storage.splits.usesSegments()) startMySegmentsSyncTasks();
|
|
81
81
|
},
|
|
82
82
|
|
|
83
83
|
// Stop periodic fetching (polling)
|
|
@@ -21,7 +21,7 @@ export function splitsSyncTaskFactory(
|
|
|
21
21
|
settings.log,
|
|
22
22
|
splitChangesUpdaterFactory(
|
|
23
23
|
settings.log,
|
|
24
|
-
splitChangesFetcherFactory(fetchSplitChanges
|
|
24
|
+
splitChangesFetcherFactory(fetchSplitChanges),
|
|
25
25
|
storage,
|
|
26
26
|
settings.sync.__splitFiltersValidation,
|
|
27
27
|
readiness.splits,
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ISplit } 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 ISplitsSyncTask extends ISyncTask<[noCache?: boolean, till?: number, splitUpdateNotification?: { payload: ISplit
|
|
7
|
+
export interface ISplitsSyncTask extends ISyncTask<[noCache?: boolean, till?: number, splitUpdateNotification?: { payload: ISplit, changeNumber: number }], boolean> { }
|
|
8
8
|
|
|
9
9
|
export interface ISegmentsSyncTask extends ISyncTask<[fetchOnlyNew?: boolean, segmentName?: string, noCache?: boolean, till?: number], boolean> { }
|
|
10
10
|
|
|
@@ -27,7 +27,7 @@ export function mySegmentsUpdaterFactory(
|
|
|
27
27
|
matchingKey: string
|
|
28
28
|
): IMySegmentsUpdater {
|
|
29
29
|
|
|
30
|
-
const { splits,
|
|
30
|
+
const { splits, segments, largeSegments } = storage;
|
|
31
31
|
let readyOnAlreadyExistentState = true;
|
|
32
32
|
let startingUp = true;
|
|
33
33
|
|
|
@@ -51,7 +51,7 @@ export function mySegmentsUpdaterFactory(
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
// Notify update if required
|
|
54
|
-
if (
|
|
54
|
+
if (splits.usesSegments() && (shouldNotifyUpdate || readyOnAlreadyExistentState)) {
|
|
55
55
|
readyOnAlreadyExistentState = false;
|
|
56
56
|
segmentsEventEmitter.emit(SDK_SEGMENTS_ARRIVED);
|
|
57
57
|
}
|
|
@@ -51,7 +51,7 @@ export function segmentChangesUpdaterFactory(
|
|
|
51
51
|
* Returned promise will not be rejected.
|
|
52
52
|
*
|
|
53
53
|
* @param fetchOnlyNew - if true, only fetch the segments that not exists, i.e., which `changeNumber` is equal to -1.
|
|
54
|
-
* This param is used by SplitUpdateWorker on server-side SDK, to fetch new registered segments on SPLIT_UPDATE
|
|
54
|
+
* This param is used by SplitUpdateWorker on server-side SDK, to fetch new registered segments on SPLIT_UPDATE notifications.
|
|
55
55
|
* @param segmentName - segment name to fetch. By passing `undefined` it fetches the list of segments registered at the storage
|
|
56
56
|
* @param noCache - true to revalidate data to fetch on a SEGMENT_UPDATE notifications.
|
|
57
57
|
* @param till - till target for the provided segmentName, for CDN bypass.
|