@splitsoftware/splitio-commons 3.0.0-rc.0 → 3.0.0-rc.1
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 +7 -2
- 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/syncTasks/definitionsSyncTask.js +1 -1
- 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 +4 -4
- package/cjs/utils/Backoff.js +20 -0
- package/cjs/utils/lang/sets.js +4 -4
- package/cjs/utils/settingsValidation/url.js +1 -1
- 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 +7 -2
- 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/syncTasks/definitionsSyncTask.js +1 -1
- 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 +3 -3
- package/esm/utils/Backoff.js +20 -0
- package/esm/utils/lang/sets.js +4 -4
- package/esm/utils/settingsValidation/url.js +1 -1
- 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 +9 -3
- package/src/services/types.ts +4 -0
- 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/syncTasks/definitionsSyncTask.ts +1 -1
- 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 +3 -3
- 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/url.ts +1 -1
- package/types/splitio.d.ts +23 -5
- 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
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { IPluggableStorageWrapper, IStorageAsync, IStorageAsyncFactory, IStorageFactoryParams, ITelemetryCacheAsync } from '../types';
|
|
2
2
|
|
|
3
3
|
import { KeyBuilderSS } from '../KeyBuilderSS';
|
|
4
|
-
import {
|
|
4
|
+
import { DefinitionsCachePluggable } from './DefinitionsCachePluggable';
|
|
5
5
|
import { SegmentsCachePluggable } from './SegmentsCachePluggable';
|
|
6
6
|
import { ImpressionsCachePluggable } from './ImpressionsCachePluggable';
|
|
7
7
|
import { EventsCachePluggable } from './EventsCachePluggable';
|
|
@@ -118,7 +118,7 @@ export function PluggableStorage(options: PluggableStorageOptions): IStorageAsyn
|
|
|
118
118
|
});
|
|
119
119
|
|
|
120
120
|
return {
|
|
121
|
-
|
|
121
|
+
definitions: new DefinitionsCachePluggable(log, keys, wrapper, settings.sync.__splitFiltersValidation),
|
|
122
122
|
rbSegments: new RBSegmentsCachePluggable(log, keys, wrapper),
|
|
123
123
|
segments: new SegmentsCachePluggable(log, keys, wrapper),
|
|
124
124
|
impressions: isPartialConsumer ? new ImpressionsCacheInMemory(impressionsQueueSize) : new ImpressionsCachePluggable(log, keys.buildImpressionsKey(), wrapper, metadata),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import SplitIO from '../../types/splitio';
|
|
2
|
-
import { IRBSegmentsCacheSync, ISegmentsCacheSync,
|
|
2
|
+
import { IRBSegmentsCacheSync, ISegmentsCacheSync, IDefinitionsCacheSync } from './types';
|
|
3
3
|
import { ILogger } from '../logger/types';
|
|
4
4
|
import { isObject } from '../utils/lang';
|
|
5
5
|
import { isConsumerMode } from '../utils/settingsValidation/mode';
|
|
@@ -27,20 +27,20 @@ export function validateRolloutPlan(log: ILogger, settings: SplitIO.ISettings):
|
|
|
27
27
|
* If `matchingKey` is provided, the storage is handled as a client-side storage (segments and largeSegments are instances of MySegmentsCache).
|
|
28
28
|
* Otherwise, the storage is handled as a server-side storage (segments is an instance of SegmentsCache).
|
|
29
29
|
*/
|
|
30
|
-
export function setRolloutPlan(log: ILogger, rolloutPlan: RolloutPlan, storage: {
|
|
31
|
-
const {
|
|
30
|
+
export function setRolloutPlan(log: ILogger, rolloutPlan: RolloutPlan, storage: { definitions?: IDefinitionsCacheSync, rbSegments?: IRBSegmentsCacheSync, segments: ISegmentsCacheSync, largeSegments?: ISegmentsCacheSync }, matchingKey?: string) {
|
|
31
|
+
const { definitions, rbSegments, segments, largeSegments } = storage;
|
|
32
32
|
const { splitChanges: { ff, rbs } } = rolloutPlan;
|
|
33
33
|
|
|
34
34
|
log.debug(`storage: set feature flags and segments${matchingKey ? ` for key ${matchingKey}` : ''}`);
|
|
35
35
|
|
|
36
|
-
if (
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
if (definitions && ff) {
|
|
37
|
+
definitions.clear();
|
|
38
|
+
definitions.update(ff.d || [], [], ff.t);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
if (rbSegments && rbs) {
|
|
42
42
|
rbSegments.clear();
|
|
43
|
-
rbSegments.update(rbs.d, [], rbs.t);
|
|
43
|
+
rbSegments.update(rbs.d || [], [], rbs.t);
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
const segmentChanges = rolloutPlan.segmentChanges;
|
package/src/storages/types.ts
CHANGED
|
@@ -194,49 +194,49 @@ export interface IPluggableStorageWrapper {
|
|
|
194
194
|
|
|
195
195
|
/** Splits cache */
|
|
196
196
|
|
|
197
|
-
export interface
|
|
197
|
+
export interface IDefinitionsCacheBase {
|
|
198
198
|
update(toAdd: IDefinition[], toRemove: string[], changeNumber: number): MaybeThenable<boolean>,
|
|
199
|
-
|
|
200
|
-
|
|
199
|
+
get(name: string): MaybeThenable<IDefinition | null>,
|
|
200
|
+
getMany(names: string[]): MaybeThenable<Record<string, IDefinition | null>>, // `fetchMany` in spec
|
|
201
201
|
// should never reject or throw an exception. Instead return -1 by default, assuming no splits are present in the storage.
|
|
202
202
|
getChangeNumber(): MaybeThenable<number>,
|
|
203
203
|
getAll(): MaybeThenable<IDefinition[]>,
|
|
204
|
-
|
|
204
|
+
getNames(): MaybeThenable<string[]>,
|
|
205
205
|
// should never reject or throw an exception. Instead return true by default, asssuming the TT might exist.
|
|
206
206
|
trafficTypeExists(trafficType: string): MaybeThenable<boolean>,
|
|
207
207
|
// only for Client-Side. Returns true if the storage is not synchronized yet (getChangeNumber() === -1) or contains a FF using segments or large segments
|
|
208
208
|
usesSegments(): MaybeThenable<boolean>,
|
|
209
209
|
clear(): MaybeThenable<boolean | void>,
|
|
210
210
|
killLocally(name: string, defaultTreatment: string, changeNumber: number): MaybeThenable<boolean>,
|
|
211
|
-
|
|
211
|
+
getNamesBySets(sets: string[]): MaybeThenable<Set<string>[]>
|
|
212
212
|
}
|
|
213
213
|
|
|
214
|
-
export interface
|
|
214
|
+
export interface IDefinitionsCacheSync extends IDefinitionsCacheBase {
|
|
215
215
|
update(toAdd: IDefinition[], toRemove: string[], changeNumber: number): boolean,
|
|
216
|
-
|
|
217
|
-
|
|
216
|
+
get(name: string): IDefinition | null,
|
|
217
|
+
getMany(names: string[]): Record<string, IDefinition | null>,
|
|
218
218
|
getChangeNumber(): number,
|
|
219
219
|
getAll(): IDefinition[],
|
|
220
|
-
|
|
220
|
+
getNames(): string[],
|
|
221
221
|
trafficTypeExists(trafficType: string): boolean,
|
|
222
222
|
usesSegments(): boolean,
|
|
223
223
|
clear(): void,
|
|
224
224
|
killLocally(name: string, defaultTreatment: string, changeNumber: number): boolean,
|
|
225
|
-
|
|
225
|
+
getNamesBySets(sets: string[]): Set<string>[]
|
|
226
226
|
}
|
|
227
227
|
|
|
228
|
-
export interface
|
|
228
|
+
export interface IDefinitionsCacheAsync extends IDefinitionsCacheBase {
|
|
229
229
|
update(toAdd: IDefinition[], toRemove: string[], changeNumber: number): Promise<boolean>,
|
|
230
|
-
|
|
231
|
-
|
|
230
|
+
get(name: string): Promise<IDefinition | null>,
|
|
231
|
+
getMany(names: string[]): Promise<Record<string, IDefinition | null>>,
|
|
232
232
|
getChangeNumber(): Promise<number>,
|
|
233
233
|
getAll(): Promise<IDefinition[]>,
|
|
234
|
-
|
|
234
|
+
getNames(): Promise<string[]>,
|
|
235
235
|
trafficTypeExists(trafficType: string): Promise<boolean>,
|
|
236
236
|
usesSegments(): Promise<boolean>,
|
|
237
237
|
clear(): Promise<boolean | void>,
|
|
238
238
|
killLocally(name: string, defaultTreatment: string, changeNumber: number): Promise<boolean>,
|
|
239
|
-
|
|
239
|
+
getNamesBySets(sets: string[]): Promise<Set<string>[]>
|
|
240
240
|
}
|
|
241
241
|
|
|
242
242
|
/** Rule-Based Segments cache */
|
|
@@ -466,7 +466,7 @@ export interface ITelemetryCacheAsync extends ITelemetryEvaluationProducerAsync,
|
|
|
466
466
|
*/
|
|
467
467
|
|
|
468
468
|
export interface IStorageBase<
|
|
469
|
-
|
|
469
|
+
TDefinitionsCache extends IDefinitionsCacheBase = IDefinitionsCacheBase,
|
|
470
470
|
TRBSegmentsCache extends IRBSegmentsCacheBase = IRBSegmentsCacheBase,
|
|
471
471
|
TSegmentsCache extends ISegmentsCacheBase = ISegmentsCacheBase,
|
|
472
472
|
TImpressionsCache extends IImpressionsCacheBase = IImpressionsCacheBase,
|
|
@@ -475,7 +475,7 @@ export interface IStorageBase<
|
|
|
475
475
|
TTelemetryCache extends ITelemetryCacheSync | ITelemetryCacheAsync = ITelemetryCacheSync | ITelemetryCacheAsync,
|
|
476
476
|
TUniqueKeysCache extends IUniqueKeysCacheBase = IUniqueKeysCacheBase
|
|
477
477
|
> {
|
|
478
|
-
|
|
478
|
+
definitions: TDefinitionsCache,
|
|
479
479
|
rbSegments: TRBSegmentsCache,
|
|
480
480
|
segments: TSegmentsCache,
|
|
481
481
|
largeSegments?: TSegmentsCache,
|
|
@@ -490,7 +490,7 @@ export interface IStorageBase<
|
|
|
490
490
|
}
|
|
491
491
|
|
|
492
492
|
export interface IStorageSync extends IStorageBase<
|
|
493
|
-
|
|
493
|
+
IDefinitionsCacheSync,
|
|
494
494
|
IRBSegmentsCacheSync,
|
|
495
495
|
ISegmentsCacheSync,
|
|
496
496
|
IImpressionsCacheSync,
|
|
@@ -505,7 +505,7 @@ export interface IStorageSync extends IStorageBase<
|
|
|
505
505
|
}
|
|
506
506
|
|
|
507
507
|
export interface IStorageAsync extends IStorageBase<
|
|
508
|
-
|
|
508
|
+
IDefinitionsCacheAsync,
|
|
509
509
|
IRBSegmentsCacheAsync,
|
|
510
510
|
ISegmentsCacheAsync,
|
|
511
511
|
IImpressionsCacheAsync | IImpressionsCacheSync,
|
|
@@ -7,7 +7,7 @@ import { syncTaskFactory } from '../../syncTask';
|
|
|
7
7
|
import { ISyncTask } from '../../types';
|
|
8
8
|
import { ISettings } from '../../../types';
|
|
9
9
|
import { CONTROL } from '../../../utils/constants';
|
|
10
|
-
import {
|
|
10
|
+
import { SDK_DEFINITIONS_ARRIVED, SDK_SEGMENTS_ARRIVED, SDK_DEFINITIONS_CACHE_LOADED, FLAGS_UPDATE, SEGMENTS_UPDATE } from '../../../readiness/constants';
|
|
11
11
|
import { SYNC_OFFLINE_DATA, ERROR_SYNC_OFFLINE_LOADING } from '../../../logger/constants';
|
|
12
12
|
|
|
13
13
|
/**
|
|
@@ -15,12 +15,12 @@ import { SYNC_OFFLINE_DATA, ERROR_SYNC_OFFLINE_LOADING } from '../../../logger/c
|
|
|
15
15
|
*/
|
|
16
16
|
export function fromObjectUpdaterFactory(
|
|
17
17
|
splitsParser: IDefinitionsParser,
|
|
18
|
-
storage: Pick<IStorageSync, '
|
|
18
|
+
storage: Pick<IStorageSync, 'definitions' | 'validateCache'>,
|
|
19
19
|
readiness: IReadinessManager,
|
|
20
20
|
settings: ISettings,
|
|
21
21
|
): () => Promise<boolean> {
|
|
22
22
|
|
|
23
|
-
const log = settings.log,
|
|
23
|
+
const log = settings.log, definitions = storage.definitions;
|
|
24
24
|
let startingUp = true;
|
|
25
25
|
|
|
26
26
|
return function objectUpdater() {
|
|
@@ -52,17 +52,17 @@ export function fromObjectUpdaterFactory(
|
|
|
52
52
|
});
|
|
53
53
|
|
|
54
54
|
return Promise.all([
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
definitions.clear(), // required to sync removed splits from mock
|
|
56
|
+
definitions.update(splits, [], Date.now())
|
|
57
57
|
]).then(() => {
|
|
58
|
-
readiness.
|
|
58
|
+
readiness.definitions.emit(SDK_DEFINITIONS_ARRIVED, { type: FLAGS_UPDATE, names: [] });
|
|
59
59
|
|
|
60
60
|
if (startingUp) {
|
|
61
61
|
startingUp = false;
|
|
62
62
|
Promise.resolve(storage.validateCache ? storage.validateCache() : { initialCacheLoad: true /* Fallback: assume initial load when validateCache doesn't exist */ }).then((cacheMetadata) => {
|
|
63
63
|
// Emits SDK_READY_FROM_CACHE
|
|
64
64
|
if (!cacheMetadata.initialCacheLoad) {
|
|
65
|
-
readiness.
|
|
65
|
+
readiness.definitions.emit(SDK_DEFINITIONS_CACHE_LOADED, cacheMetadata);
|
|
66
66
|
}
|
|
67
67
|
// Emits SDK_READY
|
|
68
68
|
readiness.segments.emit(SDK_SEGMENTS_ARRIVED, { type: SEGMENTS_UPDATE, names: [] });
|
|
@@ -81,7 +81,7 @@ export function fromObjectUpdaterFactory(
|
|
|
81
81
|
*/
|
|
82
82
|
export function fromObjectSyncTaskFactory(
|
|
83
83
|
splitsParser: IDefinitionsParser,
|
|
84
|
-
storage: Pick<IStorageSync, '
|
|
84
|
+
storage: Pick<IStorageSync, 'definitions' | 'validateCache'>,
|
|
85
85
|
readiness: IReadinessManager,
|
|
86
86
|
settings: ISettings
|
|
87
87
|
): ISyncTask<[], boolean> {
|
|
@@ -22,12 +22,12 @@ export interface ISplitChangesResponse {
|
|
|
22
22
|
ff?: {
|
|
23
23
|
t: number,
|
|
24
24
|
s?: number,
|
|
25
|
-
d
|
|
25
|
+
d?: ISplit[] | null,
|
|
26
26
|
},
|
|
27
27
|
rbs?: {
|
|
28
28
|
t: number,
|
|
29
29
|
s?: number,
|
|
30
|
-
d
|
|
30
|
+
d?: IRBSegment[] | null,
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
|
|
@@ -102,7 +102,7 @@ export function splitChangesFetcherFactory(params: ISdkFactoryContextSync): IDef
|
|
|
102
102
|
lastProxyCheckTimestamp = undefined;
|
|
103
103
|
return splitChangesFetcher(-1, undefined, undefined, -1)
|
|
104
104
|
.then((splitChangesResponse: IDefinitionChangesResponse) =>
|
|
105
|
-
Promise.all([storage.
|
|
105
|
+
Promise.all([storage.definitions.clear(), storage.rbSegments.clear()])
|
|
106
106
|
.then(() => splitChangesResponse)
|
|
107
107
|
);
|
|
108
108
|
}
|
|
@@ -5,10 +5,10 @@ import { IStorageSync } from '../../storages/types';
|
|
|
5
5
|
import { mySegmentsSyncTaskFactory } from './syncTasks/mySegmentsSyncTask';
|
|
6
6
|
import { definitionsSyncTaskFactory } from './syncTasks/definitionsSyncTask';
|
|
7
7
|
import { getMatching } from '../../utils/key';
|
|
8
|
-
import {
|
|
8
|
+
import { SDK_DEFINITIONS_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
|
-
import { usesSegmentsSync } from '../../storages/
|
|
11
|
+
import { usesSegmentsSync } from '../../storages/AbstractDefinitionsCacheSync';
|
|
12
12
|
import { SdkUpdateMetadata } from '../../../types/splitio';
|
|
13
13
|
import { IDefinitionChangesFetcher } from './fetchers/types';
|
|
14
14
|
|
|
@@ -45,7 +45,7 @@ export function pollingManagerCSFactory(
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
// smart pausing
|
|
48
|
-
readiness.
|
|
48
|
+
readiness.definitions.on(SDK_DEFINITIONS_ARRIVED, () => {
|
|
49
49
|
if (!definitionsSyncTask.isRunning()) return; // noop if not doing polling
|
|
50
50
|
const usingSegments = usesSegmentsSync(storage);
|
|
51
51
|
if (usingSegments !== mySegmentsSyncTask.isRunning()) {
|
|
@@ -66,7 +66,7 @@ export function pollingManagerCSFactory(
|
|
|
66
66
|
if (!readiness.isReady() && !usesSegmentsSync(storage)) readiness.segments.emit(SDK_SEGMENTS_ARRIVED, metadata);
|
|
67
67
|
}
|
|
68
68
|
if (!usesSegmentsSync(storage)) setTimeout(smartReady, 0);
|
|
69
|
-
else readiness.
|
|
69
|
+
else readiness.definitions.once(SDK_DEFINITIONS_ARRIVED, smartReady);
|
|
70
70
|
|
|
71
71
|
mySegmentsSyncTasks[matchingKey] = mySegmentsSyncTask;
|
|
72
72
|
return mySegmentsSyncTask;
|
|
@@ -23,7 +23,7 @@ export function definitionsSyncTaskFactory(
|
|
|
23
23
|
definitionChangesFetcher,
|
|
24
24
|
storage,
|
|
25
25
|
settings.sync.__splitFiltersValidation,
|
|
26
|
-
readiness.
|
|
26
|
+
readiness.definitions,
|
|
27
27
|
settings.startup.requestTimeoutBeforeReady,
|
|
28
28
|
settings.startup.retriesOnFailureBeforeReady,
|
|
29
29
|
isClientSide
|
|
@@ -4,7 +4,7 @@ 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 IDefinitionsSyncTask extends ISyncTask<[noCache?: boolean, till?: number,
|
|
7
|
+
export interface IDefinitionsSyncTask extends ISyncTask<[noCache?: boolean, till?: number, definitionUpdateNotification?: { 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
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { ISegmentsCacheBase, IStorageBase } from '../../../storages/types';
|
|
2
2
|
import { IDefinitionChangesFetcher } from '../fetchers/types';
|
|
3
3
|
import { IRBSegment, IDefinition, IDefinitionChangesResponse, ISplitFiltersValidation, MaybeThenable } from '../../../dtos/types';
|
|
4
|
-
import {
|
|
4
|
+
import { IDefinitionsEventEmitter } from '../../../readiness/types';
|
|
5
5
|
import { timeout } from '../../../utils/promise/timeout';
|
|
6
|
-
import {
|
|
6
|
+
import { SDK_DEFINITIONS_ARRIVED, FLAGS_UPDATE, SEGMENTS_UPDATE, CONFIGS_UPDATE } from '../../../readiness/constants';
|
|
7
7
|
import { ILogger } from '../../../logger/types';
|
|
8
8
|
import { SYNC_FETCH, SYNC_UPDATE, SYNC_FETCH_FAILS, SYNC_FETCH_RETRY } from '../../../logger/constants';
|
|
9
9
|
import { startsWith } from '../../../utils/lang';
|
|
@@ -128,14 +128,14 @@ function convertInstantUpdateToDefinitionChanges(instantUpdate: InstantUpdate) {
|
|
|
128
128
|
export function definitionChangesUpdaterFactory(
|
|
129
129
|
log: ILogger,
|
|
130
130
|
definitionChangesFetcher: IDefinitionChangesFetcher,
|
|
131
|
-
storage: Pick<IStorageBase, '
|
|
131
|
+
storage: Pick<IStorageBase, 'definitions' | 'rbSegments' | 'segments' | 'save'>,
|
|
132
132
|
splitFiltersValidation: ISplitFiltersValidation,
|
|
133
|
-
|
|
133
|
+
definitionsEventEmitter?: IDefinitionsEventEmitter,
|
|
134
134
|
requestTimeoutBeforeReady = 0,
|
|
135
135
|
retriesOnFailureBeforeReady = 0,
|
|
136
136
|
isClientSide?: boolean
|
|
137
137
|
): DefinitionChangesUpdater {
|
|
138
|
-
const {
|
|
138
|
+
const { definitions, rbSegments, segments } = storage;
|
|
139
139
|
|
|
140
140
|
let startingUp = true;
|
|
141
141
|
|
|
@@ -183,7 +183,7 @@ export function definitionChangesUpdaterFactory(
|
|
|
183
183
|
const { added, removed, names } = computeMutation(definitionChanges.d, usedSegments, splitFiltersValidation);
|
|
184
184
|
updatedDefinitions = names;
|
|
185
185
|
log.debug(SYNC_UPDATE, [definitionChangesFetcher.type, added.length, removed.length]);
|
|
186
|
-
ffUpdate =
|
|
186
|
+
ffUpdate = definitions.update(added, removed, definitionChanges.d.till);
|
|
187
187
|
}
|
|
188
188
|
|
|
189
189
|
let rbsUpdate: MaybeThenable<boolean> = false;
|
|
@@ -201,9 +201,9 @@ export function definitionChangesUpdaterFactory(
|
|
|
201
201
|
|
|
202
202
|
startingUp = false;
|
|
203
203
|
|
|
204
|
-
if (
|
|
205
|
-
// To emit
|
|
206
|
-
return Promise.resolve(!
|
|
204
|
+
if (definitionsEventEmitter) {
|
|
205
|
+
// To emit SDK_DEFINITIONS_ARRIVED for server-side SDK, we must check that all registered segments have been fetched
|
|
206
|
+
return Promise.resolve(!definitionsEventEmitter.definitionsArrived || ((ffChanged || rbsChanged) && (isClientSide || checkAllSegmentsExist(segments))))
|
|
207
207
|
.catch(() => false /** noop. just to handle a possible `checkAllSegmentsExist` rejection, before emitting SDK event */)
|
|
208
208
|
.then(emitSplitsArrivedEvent => {
|
|
209
209
|
// emit SDK events
|
|
@@ -212,7 +212,7 @@ export function definitionChangesUpdaterFactory(
|
|
|
212
212
|
type: updatedDefinitions.length > 0 ? definitionChangesFetcher.type === 'configs' ? CONFIGS_UPDATE : FLAGS_UPDATE : SEGMENTS_UPDATE,
|
|
213
213
|
names: updatedDefinitions.length > 0 ? updatedDefinitions : []
|
|
214
214
|
};
|
|
215
|
-
|
|
215
|
+
definitionsEventEmitter.emit(SDK_DEFINITIONS_ARRIVED, metadata);
|
|
216
216
|
}
|
|
217
217
|
return true;
|
|
218
218
|
});
|
|
@@ -234,6 +234,6 @@ export function definitionChangesUpdaterFactory(
|
|
|
234
234
|
}
|
|
235
235
|
|
|
236
236
|
// `getChangeNumber` never rejects or throws error
|
|
237
|
-
return Promise.all([
|
|
237
|
+
return Promise.all([definitions.getChangeNumber(), rbSegments.getChangeNumber()]).then(_definitionChangesUpdater);
|
|
238
238
|
};
|
|
239
239
|
}
|
|
@@ -8,7 +8,7 @@ import { SYNC_FETCH_RETRY } from '../../../logger/constants';
|
|
|
8
8
|
import { MySegmentsData } from '../types';
|
|
9
9
|
import { IMembershipsResponse } from '../../../dtos/types';
|
|
10
10
|
import { MEMBERSHIPS_LS_UPDATE } from '../../streaming/constants';
|
|
11
|
-
import { usesSegmentsSync } from '../../../storages/
|
|
11
|
+
import { usesSegmentsSync } from '../../../storages/AbstractDefinitionsCacheSync';
|
|
12
12
|
|
|
13
13
|
type IMySegmentsUpdater = (segmentsData?: MySegmentsData, noCache?: boolean, till?: number) => Promise<boolean>
|
|
14
14
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { IFetchAuth } from '../../../services/types';
|
|
2
|
-
import { IAuthenticate,
|
|
2
|
+
import { IAuthenticate, IJwtCredentialV2 } from './types';
|
|
3
3
|
import { objectAssign } from '../../../utils/lang/objectAssign';
|
|
4
4
|
import { encodeToBase64 } from '../../../utils/base64';
|
|
5
5
|
import { decodeJWTtoken } from '../../../utils/jwt';
|
|
@@ -16,7 +16,7 @@ export function authenticateFactory(fetchAuth: IFetchAuth): IAuthenticate {
|
|
|
16
16
|
* Run authentication requests to Auth Server, and returns a promise that resolves with the decoded JTW token.
|
|
17
17
|
* @param userKeys - set of user Keys to track membership updates. It is undefined for server-side API.
|
|
18
18
|
*/
|
|
19
|
-
return function authenticate(userKeys?: string[]): Promise<
|
|
19
|
+
return function authenticate(userKeys?: string[]): Promise<IJwtCredentialV2> {
|
|
20
20
|
return fetchAuth(userKeys)
|
|
21
21
|
.then(resp => resp.json())
|
|
22
22
|
.then(json => {
|
|
@@ -1,20 +1,23 @@
|
|
|
1
1
|
import { IDecodedJWTToken } from '../../../utils/jwt/types';
|
|
2
2
|
|
|
3
|
-
export
|
|
4
|
-
pushEnabled:
|
|
5
|
-
token: string
|
|
3
|
+
export type IJwtCredentialV2 = {
|
|
4
|
+
pushEnabled: boolean
|
|
5
|
+
token: string // empty string ("") when `"pushEnabled": false`
|
|
6
6
|
decodedToken: IDecodedJWTToken
|
|
7
7
|
channels: { [channel: string]: string[] }
|
|
8
8
|
connDelay?: number
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
export
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
export type IJwtCredentialV3 = {
|
|
12
|
+
token: string
|
|
13
|
+
decodedToken: IDecodedJWTToken
|
|
14
|
+
channels: { [channel: string]: string[] }
|
|
15
|
+
config?: {
|
|
16
|
+
streaming?: {
|
|
17
|
+
delay?: number
|
|
18
|
+
enabled?: boolean
|
|
19
|
+
} | null;
|
|
20
|
+
} | null;
|
|
14
21
|
}
|
|
15
22
|
|
|
16
|
-
export type
|
|
17
|
-
|
|
18
|
-
export type IAuthenticate = (userKeys?: string[]) => Promise<IAuthToken>
|
|
19
|
-
|
|
20
|
-
export type IAuthenticateV2 = (isClientSide?: boolean) => Promise<IAuthToken>
|
|
23
|
+
export type IAuthenticate = (userKeys?: string[]) => Promise<IJwtCredentialV2>
|
|
@@ -5,7 +5,7 @@ import { ISettings } from '../../../types';
|
|
|
5
5
|
import { checkIfServerSide } from '../../../utils/key';
|
|
6
6
|
import { isString } from '../../../utils/lang';
|
|
7
7
|
import { objectAssign } from '../../../utils/lang/objectAssign';
|
|
8
|
-
import {
|
|
8
|
+
import { IJwtCredentialV2 } from '../AuthClient/types';
|
|
9
9
|
import { ISSEClient, ISseEventHandler } from './types';
|
|
10
10
|
|
|
11
11
|
const ABLY_API_VERSION = '1.1';
|
|
@@ -66,7 +66,7 @@ export class SSEClient implements ISSEClient {
|
|
|
66
66
|
/**
|
|
67
67
|
* Open the connection with a given authToken
|
|
68
68
|
*/
|
|
69
|
-
open(authToken:
|
|
69
|
+
open(authToken: IJwtCredentialV2) {
|
|
70
70
|
this.close(); // it closes connection if previously opened
|
|
71
71
|
|
|
72
72
|
const channelsQueryParam = Object.keys(authToken.channels).map((channel) => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IJwtCredentialV2 } from '../AuthClient/types';
|
|
2
2
|
|
|
3
3
|
export interface ISseEventHandler {
|
|
4
4
|
handleError: (ev: Event) => any;
|
|
@@ -7,7 +7,7 @@ export interface ISseEventHandler {
|
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
export interface ISSEClient {
|
|
10
|
-
open(authToken:
|
|
10
|
+
open(authToken: IJwtCredentialV2): void,
|
|
11
11
|
close(): void,
|
|
12
12
|
setEventHandler(handler: ISseEventHandler): void
|
|
13
13
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ITelemetryTracker } from '../../../trackers/types';
|
|
2
2
|
import { CONNECTION_ESTABLISHED, DISABLED, ENABLED, OCCUPANCY_PRI, OCCUPANCY_SEC, PAUSED, STREAMING_STATUS } from '../../../utils/constants';
|
|
3
3
|
import { StreamingEventType } from '../../submitters/types';
|
|
4
|
-
import { ControlType, PUSH_SUBSYSTEM_UP,
|
|
4
|
+
import { ControlType, PUSH_SUBSYSTEM_UP, PUSH_NON_RETRYABLE_ERROR, PUSH_SUBSYSTEM_DOWN } from '../constants';
|
|
5
5
|
import { IPushEventEmitter } from '../types';
|
|
6
6
|
|
|
7
7
|
const CONTROL_CHANNEL_REGEXS = [/control_pri$/, /control_sec$/];
|
|
@@ -84,7 +84,7 @@ export function notificationKeeperFactory(pushEmitter: IPushEventEmitter, teleme
|
|
|
84
84
|
c.cTime = timestamp;
|
|
85
85
|
if (controlType === ControlType.STREAMING_DISABLED) {
|
|
86
86
|
telemetryTracker.streamingEvent(STREAMING_STATUS, DISABLED);
|
|
87
|
-
pushEmitter.emit(
|
|
87
|
+
pushEmitter.emit(PUSH_NON_RETRYABLE_ERROR);
|
|
88
88
|
} else if (hasPublishers) {
|
|
89
89
|
if (controlType === ControlType.STREAMING_PAUSED && hasResumed) {
|
|
90
90
|
telemetryTracker.streamingEvent(STREAMING_STATUS, PAUSED);
|
|
@@ -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 { IPushEventEmitter } from '../types';
|
|
5
5
|
import { ISseEventHandler } from '../SSEClient/types';
|
|
6
6
|
import { INotificationError, INotificationMessage } from './types';
|
|
@@ -56,7 +56,7 @@ export function SSEHandlerFactory(log: ILogger, pushEmitter: IPushEventEmitter,
|
|
|
56
56
|
if (isRetryableError(errorWithParsedData)) {
|
|
57
57
|
pushEmitter.emit(PUSH_RETRYABLE_ERROR);
|
|
58
58
|
} else {
|
|
59
|
-
pushEmitter.emit(
|
|
59
|
+
pushEmitter.emit(PUSH_NON_RETRYABLE_ERROR);
|
|
60
60
|
}
|
|
61
61
|
},
|
|
62
62
|
|
package/src/sync/streaming/UpdateWorkers/{SplitsUpdateWorker.ts → DefinitionsUpdateWorker.ts}
RENAMED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { IRBSegment, IDefinition } from '../../../dtos/types';
|
|
2
2
|
import { STREAMING_PARSING_SPLIT_UPDATE } from '../../../logger/constants';
|
|
3
3
|
import { ILogger } from '../../../logger/types';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { IRBSegmentsCacheSync,
|
|
4
|
+
import { SDK_DEFINITIONS_ARRIVED } from '../../../readiness/constants';
|
|
5
|
+
import { IDefinitionsEventEmitter } from '../../../readiness/types';
|
|
6
|
+
import { IRBSegmentsCacheSync, IDefinitionsCacheSync, IStorageSync } from '../../../storages/types';
|
|
7
7
|
import { ITelemetryTracker } from '../../../trackers/types';
|
|
8
8
|
import { Backoff } from '../../../utils/Backoff';
|
|
9
9
|
import { SPLITS } from '../../../utils/constants';
|
|
@@ -16,22 +16,22 @@ import { FETCH_BACKOFF_BASE, FETCH_BACKOFF_MAX_WAIT, FETCH_BACKOFF_MAX_RETRIES }
|
|
|
16
16
|
import { IUpdateWorker } from './types';
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
|
-
*
|
|
19
|
+
* DefinitionsUpdateWorker factory
|
|
20
20
|
*/
|
|
21
|
-
export function
|
|
21
|
+
export function DefinitionsUpdateWorker(log: ILogger, storage: IStorageSync, definitionsSyncTask: IDefinitionsSyncTask, definitionsEventEmitter: IDefinitionsEventEmitter, telemetryTracker: ITelemetryTracker, segmentsSyncTask?: ISegmentsSyncTask): IUpdateWorker<[updateData: ISplitUpdateData]> & { killDefinition(event: ISplitKillData): void } {
|
|
22
22
|
|
|
23
|
-
const ff =
|
|
24
|
-
const rbs =
|
|
23
|
+
const ff = DefinitionsUpdateWorker(storage.definitions);
|
|
24
|
+
const rbs = DefinitionsUpdateWorker(storage.rbSegments);
|
|
25
25
|
|
|
26
|
-
function
|
|
26
|
+
function DefinitionsUpdateWorker(cache: IDefinitionsCacheSync | IRBSegmentsCacheSync) {
|
|
27
27
|
let maxChangeNumber = -1;
|
|
28
28
|
let handleNewEvent = false;
|
|
29
29
|
let isHandlingEvent: boolean;
|
|
30
30
|
let cdnBypass: boolean;
|
|
31
31
|
let instantUpdate: InstantUpdate | undefined;
|
|
32
|
-
const backoff = new Backoff(
|
|
32
|
+
const backoff = new Backoff(__handleDefinitionUpdateCall, FETCH_BACKOFF_BASE, FETCH_BACKOFF_MAX_WAIT);
|
|
33
33
|
|
|
34
|
-
function
|
|
34
|
+
function __handleDefinitionUpdateCall() {
|
|
35
35
|
isHandlingEvent = true;
|
|
36
36
|
if (maxChangeNumber > cache.getChangeNumber()) {
|
|
37
37
|
handleNewEvent = false;
|
|
@@ -39,7 +39,7 @@ export function SplitsUpdateWorker(log: ILogger, storage: IStorageSync, definiti
|
|
|
39
39
|
definitionsSyncTask.execute(true, cdnBypass ? maxChangeNumber : undefined, instantUpdate).then(() => {
|
|
40
40
|
if (!isHandlingEvent) return; // halt if `stop` has been called
|
|
41
41
|
if (handleNewEvent) {
|
|
42
|
-
|
|
42
|
+
__handleDefinitionUpdateCall();
|
|
43
43
|
} else {
|
|
44
44
|
if (instantUpdate) telemetryTracker.trackUpdatesFromSSE(SPLITS);
|
|
45
45
|
// fetch new registered segments for server-side API. Not retrying on error
|
|
@@ -64,7 +64,7 @@ export function SplitsUpdateWorker(log: ILogger, storage: IStorageSync, definiti
|
|
|
64
64
|
} else {
|
|
65
65
|
backoff.reset();
|
|
66
66
|
cdnBypass = true;
|
|
67
|
-
|
|
67
|
+
__handleDefinitionUpdateCall();
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
});
|
|
@@ -93,7 +93,7 @@ export function SplitsUpdateWorker(log: ILogger, storage: IStorageSync, definiti
|
|
|
93
93
|
instantUpdate = { payload, changeNumber, type };
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
-
if (backoff.timeoutID || !isHandlingEvent)
|
|
96
|
+
if (backoff.timeoutID || !isHandlingEvent) __handleDefinitionUpdateCall();
|
|
97
97
|
backoff.reset();
|
|
98
98
|
},
|
|
99
99
|
stop() {
|
|
@@ -128,10 +128,10 @@ export function SplitsUpdateWorker(log: ILogger, storage: IStorageSync, definiti
|
|
|
128
128
|
* @param splitName - name of split to kill
|
|
129
129
|
* @param defaultTreatment - default treatment value
|
|
130
130
|
*/
|
|
131
|
-
|
|
132
|
-
if (storage.
|
|
131
|
+
killDefinition({ changeNumber, splitName, defaultTreatment }: ISplitKillData) {
|
|
132
|
+
if (storage.definitions.killLocally(splitName, defaultTreatment, changeNumber)) {
|
|
133
133
|
// trigger an SDK_UPDATE if Split was killed locally
|
|
134
|
-
|
|
134
|
+
definitionsEventEmitter.emit(SDK_DEFINITIONS_ARRIVED, true);
|
|
135
135
|
}
|
|
136
136
|
// queues the SplitChanges fetch (only if changeNumber is newer)
|
|
137
137
|
ff.put({ changeNumber } as ISplitUpdateData);
|
|
@@ -6,7 +6,7 @@ export const SECONDS_BEFORE_EXPIRATION = 600;
|
|
|
6
6
|
* emitted on SSE and Authenticate non-recoverable errors, STREAMING_DISABLED control notification and authentication with pushEnabled false
|
|
7
7
|
* triggers `handleNonRetryableError` call
|
|
8
8
|
*/
|
|
9
|
-
export const
|
|
9
|
+
export const PUSH_NON_RETRYABLE_ERROR = 'PUSH_NON_RETRYABLE_ERROR';
|
|
10
10
|
/**
|
|
11
11
|
* emitted on SSE and Authenticate recoverable errors
|
|
12
12
|
* triggers `handleRetryableError` call
|
|
@@ -19,7 +19,7 @@ export const PUSH_RETRYABLE_ERROR = 'PUSH_RETRYABLE_ERROR';
|
|
|
19
19
|
export const PUSH_SUBSYSTEM_UP = 'PUSH_SUBSYSTEM_UP';
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
|
-
* emitted on STREAMING_PAUSED control notification, OCCUPANCY equal to 0,
|
|
22
|
+
* emitted on STREAMING_PAUSED control notification, OCCUPANCY equal to 0, PUSH_NON_RETRYABLE_ERROR and PUSH_RETRYABLE_ERROR events.
|
|
23
23
|
* triggers `startPolling` and `stopWorkers` calls
|
|
24
24
|
*/
|
|
25
25
|
export const PUSH_SUBSYSTEM_DOWN = 'PUSH_SUBSYSTEM_DOWN';
|