Skip to content

Commit 40124f7

Browse files
Refactor Split cache: add 'update' method
1 parent 2a20458 commit 40124f7

File tree

21 files changed

+319
-389
lines changed

21 files changed

+319
-389
lines changed

src/logger/constants.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,7 @@ export const RETRIEVE_CLIENT_EXISTING = 28;
2020
export const RETRIEVE_MANAGER = 29;
2121
export const SYNC_OFFLINE_DATA = 30;
2222
export const SYNC_SPLITS_FETCH = 31;
23-
export const SYNC_SPLITS_NEW = 32;
24-
export const SYNC_SPLITS_REMOVED = 33;
25-
export const SYNC_SPLITS_SEGMENTS = 34;
23+
export const SYNC_SPLITS_UPDATE = 32;
2624
export const STREAMING_NEW_MESSAGE = 35;
2725
export const SYNC_TASK_START = 36;
2826
export const SYNC_TASK_EXECUTE = 37;

src/logger/messages/debug.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,7 @@ export const codesDebug: [number, string][] = codesInfo.concat([
2121
// synchronizer
2222
[c.SYNC_OFFLINE_DATA, c.LOG_PREFIX_SYNC_OFFLINE + 'Feature flags data: \n%s'],
2323
[c.SYNC_SPLITS_FETCH, c.LOG_PREFIX_SYNC_SPLITS + 'Spin up feature flags update using since = %s'],
24-
[c.SYNC_SPLITS_NEW, c.LOG_PREFIX_SYNC_SPLITS + 'New feature flags %s'],
25-
[c.SYNC_SPLITS_REMOVED, c.LOG_PREFIX_SYNC_SPLITS + 'Removed feature flags %s'],
26-
[c.SYNC_SPLITS_SEGMENTS, c.LOG_PREFIX_SYNC_SPLITS + 'Segment names collected %s'],
24+
[c.SYNC_SPLITS_UPDATE, c.LOG_PREFIX_SYNC_SPLITS + 'New feature flags %s. Removed feature flags %s. Segment names collected %s'],
2725
[c.STREAMING_NEW_MESSAGE, c.LOG_PREFIX_SYNC_STREAMING + 'New SSE message received, with data: %s.'],
2826
[c.SYNC_TASK_START, c.LOG_PREFIX_SYNC + ': Starting %s. Running each %s millis'],
2927
[c.SYNC_TASK_EXECUTE, c.LOG_PREFIX_SYNC + ': Running %s'],

src/sdkManager/__tests__/index.asyncCache.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ describe('Manager with async cache', () => {
3333
const cache = new SplitsCacheInRedis(loggerMock, keys, connection);
3434
const manager = sdkManagerFactory({ mode: 'consumer', log: loggerMock }, cache, sdkReadinessManagerMock);
3535
await cache.clear();
36-
await cache.addSplit(splitObject.name, splitObject as any);
36+
await cache.addSplit(splitObject as any);
3737

3838
/** List all splits */
3939
const views = await manager.splits();

src/sdkManager/__tests__/index.syncCache.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ describe('Manager with sync cache (In Memory)', () => {
1919
/** Setup: create manager */
2020
const cache = new SplitsCacheInMemory();
2121
const manager = sdkManagerFactory({ mode: 'standalone', log: loggerMock }, cache, sdkReadinessManagerMock);
22-
cache.addSplit(splitObject.name, splitObject as any);
22+
cache.addSplit(splitObject as any);
2323

2424
test('List all splits', () => {
2525

src/storages/AbstractSplitsCacheAsync.ts

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,22 @@ import { objectAssign } from '../utils/lang/objectAssign';
88
*/
99
export abstract class AbstractSplitsCacheAsync implements ISplitsCacheAsync {
1010

11-
abstract addSplit(name: string, split: ISplit): Promise<boolean>
12-
abstract addSplits(entries: [string, ISplit][]): Promise<boolean[] | void>
13-
abstract removeSplits(names: string[]): Promise<boolean[] | void>
11+
protected abstract setChangeNumber(changeNumber: number): Promise<boolean | void>
12+
protected abstract addSplit(split: ISplit): Promise<boolean>
13+
protected abstract removeSplit(name: string): Promise<boolean>
14+
15+
update(addedFFs: ISplit[], removedFFs: ISplit[], changeNumber: number): Promise<boolean> {
16+
return Promise.all([
17+
this.setChangeNumber(changeNumber),
18+
Promise.all(addedFFs.map(addedFF => this.addSplit(addedFF))),
19+
Promise.all(removedFFs.map(removedFF => this.removeSplit(removedFF.name)))
20+
]).then(([, added, removed]) => {
21+
return added.some(result => result) || removed.some(result => result);
22+
});
23+
}
24+
1425
abstract getSplit(name: string): Promise<ISplit | null>
1526
abstract getSplits(names: string[]): Promise<Record<string, ISplit | null>>
16-
abstract setChangeNumber(changeNumber: number): Promise<boolean | void>
1727
abstract getChangeNumber(): Promise<number>
1828
abstract getAll(): Promise<ISplit[]>
1929
abstract getSplitNames(): Promise<string[]>
@@ -52,7 +62,7 @@ export abstract class AbstractSplitsCacheAsync implements ISplitsCacheAsync {
5262
newSplit.defaultTreatment = defaultTreatment;
5363
newSplit.changeNumber = changeNumber;
5464

55-
return this.addSplit(name, newSplit);
65+
return this.addSplit(newSplit);
5666
}
5767
return false;
5868
}).catch(() => false);

src/storages/AbstractSplitsCacheSync.ts

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,14 @@ import { IN_SEGMENT, IN_LARGE_SEGMENT } from '../utils/constants';
99
*/
1010
export abstract class AbstractSplitsCacheSync implements ISplitsCacheSync {
1111

12-
abstract addSplit(name: string, split: ISplit): boolean
13-
14-
addSplits(entries: [string, ISplit][]): boolean[] {
15-
return entries.map(keyValuePair => this.addSplit(keyValuePair[0], keyValuePair[1]));
16-
}
17-
18-
abstract removeSplit(name: string): boolean
19-
20-
removeSplits(names: string[]): boolean[] {
21-
return names.map(name => this.removeSplit(name));
12+
protected abstract setChangeNumber(changeNumber: number): boolean | void
13+
protected abstract addSplit(split: ISplit): boolean
14+
protected abstract removeSplit(name: string): boolean
15+
16+
update(addedFFs: ISplit[], removedFFs: ISplit[], changeNumber: number): boolean {
17+
this.setChangeNumber(changeNumber);
18+
const updated = addedFFs.map(addedFF => this.addSplit(addedFF)).some(result => result);
19+
return removedFFs.map(removedFF => this.removeSplit(removedFF.name)).some(result => result) || updated;
2220
}
2321

2422
abstract getSplit(name: string): ISplit | null
@@ -31,8 +29,6 @@ export abstract class AbstractSplitsCacheSync implements ISplitsCacheSync {
3129
return splits;
3230
}
3331

34-
abstract setChangeNumber(changeNumber: number): boolean | void
35-
3632
abstract getChangeNumber(): number
3733

3834
getAll(): ISplit[] {
@@ -71,7 +67,7 @@ export abstract class AbstractSplitsCacheSync implements ISplitsCacheSync {
7167
newSplit.defaultTreatment = defaultTreatment;
7268
newSplit.changeNumber = changeNumber;
7369

74-
return this.addSplit(name, newSplit);
70+
return this.addSplit(newSplit);
7571
}
7672
return false;
7773
}

src/storages/__tests__/testUtils.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ export function assertSyncRecorderCacheInterface(cache: IEventsCacheSync | IImpr
2323
// Split mocks
2424

2525
//@ts-ignore
26-
export const splitWithUserTT: ISplit = { trafficTypeName: 'user_tt', conditions: [] };
26+
export const splitWithUserTT: ISplit = { name: 'user_ff', trafficTypeName: 'user_tt', conditions: [] };
2727
//@ts-ignore
28-
export const splitWithAccountTT: ISplit = { trafficTypeName: 'account_tt', conditions: [] };
28+
export const splitWithAccountTT: ISplit = { name: 'account_ff', trafficTypeName: 'account_tt', conditions: [] };
2929
//@ts-ignore
3030
export const splitWithAccountTTAndUsesSegments: ISplit = { trafficTypeName: 'account_tt', conditions: [{ matcherGroup: { matchers: [{ matcherType: 'IN_SEGMENT', userDefinedSegmentMatcherData: { segmentName: 'employees' } }] } }] };
3131
//@ts-ignore

src/storages/dataLoader.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,9 @@ export function dataLoaderFactory(preloadedData: PreloadedData): DataLoader {
3535

3636
// cleaning up the localStorage data, since some cached splits might need be part of the preloaded data
3737
storage.splits.clear();
38-
storage.splits.setChangeNumber(since);
3938

4039
// splitsData in an object where the property is the split name and the pertaining value is a stringified json of its data
41-
storage.splits.addSplits(Object.keys(splitsData).map(splitName => JSON.parse(splitsData[splitName])));
40+
storage.splits.update(Object.keys(splitsData).map(splitName => JSON.parse(splitsData[splitName])), [], since);
4241

4342
// add mySegments data
4443
let mySegmentsData = preloadedData.mySegmentsData && preloadedData.mySegmentsData[userId];

src/storages/inLocalStorage/SplitsCacheInLocal.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,9 @@ export class SplitsCacheInLocal extends AbstractSplitsCacheSync {
9696
this.hasSync = false;
9797
}
9898

99-
addSplit(name: string, split: ISplit) {
99+
addSplit(split: ISplit) {
100100
try {
101+
const name = split.name;
101102
const splitKey = this.keys.buildSplitKey(name);
102103
const splitFromLocalStorage = localStorage.getItem(splitKey);
103104
const previousSplit = splitFromLocalStorage ? JSON.parse(splitFromLocalStorage) : null;

0 commit comments

Comments
 (0)