Skip to content

Commit 60ccbf8

Browse files
Add RBSegments
1 parent a6598a4 commit 60ccbf8

File tree

6 files changed

+38
-8
lines changed

6 files changed

+38
-8
lines changed

src/storages/__tests__/dataLoader.spec.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ test('loadData & getSnapshot', () => {
99
const onReadyFromCacheCb = jest.fn();
1010
// @ts-expect-error
1111
const serverStorage = InMemoryStorageFactory({ settings: fullSettings }); // @ts-expect-error
12-
serverStorage.splits.update([{ name: 'split1' }], [], 123);
12+
serverStorage.splits.update([{ name: 'split1' }], [], 123); // @ts-expect-error
13+
serverStorage.rbSegments.update([{ name: 'rbs1' }], [], 321);
1314
serverStorage.segments.update('segment1', [fullSettings.core.key as string], [], 123);
1415

1516
const preloadedData = dataLoader.getSnapshot(serverStorage, [fullSettings.core.key as string]);
@@ -24,6 +25,8 @@ test('loadData & getSnapshot', () => {
2425
expect(preloadedData).toEqual({
2526
since: 123,
2627
flags: [{ name: 'split1' }],
28+
rbSince: 321,
29+
rbSegments: [{ name: 'rbs1' }],
2730
memberships: { [fullSettings.core.key as string]: { ms: { k: [{ n: 'segment1' }] }, ls: { k: [] } } },
2831
segments: undefined
2932
});

src/storages/dataLoader.ts

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,26 @@
11
import SplitIO from '../../types/splitio';
2-
import { ISegmentsCacheSync, ISplitsCacheSync, IStorageSync } from './types';
2+
import { IRBSegmentsCacheSync, ISegmentsCacheSync, ISplitsCacheSync, IStorageSync } from './types';
33
import { setToArray } from '../utils/lang/sets';
44
import { getMatching } from '../utils/key';
5-
import { IMembershipsResponse, IMySegmentsResponse, ISplit } from '../dtos/types';
5+
import { IMembershipsResponse, IMySegmentsResponse, IRBSegment, ISplit } from '../dtos/types';
66

77
/**
88
*
99
* @param preloadedData - validated data
1010
* @param storage - object containing `splits` and `segments` cache (client-side variant)
1111
* @param userKey - user key (matching key) of the provided MySegmentsCache
1212
*
13+
* @TODO load data even if current data is more recent?
1314
* @TODO extend to load largeSegments
1415
* @TODO extend to load data on shared mySegments storages. Be specific when emitting SDK_READY_FROM_CACHE on shared clients. Maybe the serializer should provide the `useSegments` flag.
1516
* @TODO add logs, and input validation in this module, in favor of size reduction.
1617
* @TODO unit tests
1718
*/
18-
export function loadData(preloadedData: SplitIO.PreloadedData, storage: { splits?: ISplitsCacheSync, segments: ISegmentsCacheSync, largeSegments?: ISegmentsCacheSync }, matchingKey?: string) {
19+
export function loadData(preloadedData: SplitIO.PreloadedData, storage: { splits?: ISplitsCacheSync, rbSegments?: IRBSegmentsCacheSync, segments: ISegmentsCacheSync, largeSegments?: ISegmentsCacheSync }, matchingKey?: string) {
1920
// Do not load data if current preloadedData is empty
2021
if (Object.keys(preloadedData).length === 0) return;
2122

22-
const { segments = {}, since = -1, flags = [] } = preloadedData;
23+
const { segments = {}, since = -1, flags = [], rbSince = -1, rbSegments = [] } = preloadedData;
2324

2425
if (storage.splits) {
2526
const storedSince = storage.splits.getChangeNumber();
@@ -34,6 +35,19 @@ export function loadData(preloadedData: SplitIO.PreloadedData, storage: { splits
3435
storage.splits.update(flags as ISplit[], [], since);
3536
}
3637

38+
if (storage.rbSegments) {
39+
const storedSince = storage.rbSegments.getChangeNumber();
40+
41+
// Do not load data if current data is more recent
42+
if (storedSince > rbSince) return;
43+
44+
// cleaning up the localStorage data, since some cached splits might need be part of the preloaded data
45+
storage.rbSegments.clear();
46+
47+
// splitsData in an object where the property is the split name and the pertaining value is a stringified json of its data
48+
storage.rbSegments.update(rbSegments as IRBSegment[], [], rbSince);
49+
}
50+
3751
if (matchingKey) { // add memberships data (client-side)
3852
let memberships = preloadedData.memberships && preloadedData.memberships[matchingKey];
3953
if (!memberships && segments) {
@@ -61,9 +75,10 @@ export function loadData(preloadedData: SplitIO.PreloadedData, storage: { splits
6175

6276
export function getSnapshot(storage: IStorageSync, userKeys?: SplitIO.SplitKey[]): SplitIO.PreloadedData {
6377
return {
64-
// lastUpdated: Date.now(),
6578
since: storage.splits.getChangeNumber(),
6679
flags: storage.splits.getAll(),
80+
rbSince: storage.rbSegments.getChangeNumber(),
81+
rbSegments: storage.rbSegments.getAll(),
6782
segments: userKeys ?
6883
undefined : // @ts-ignore accessing private prop
6984
Object.keys(storage.segments.segmentCache).reduce((prev, cur) => { // @ts-ignore accessing private prop

src/storages/inLocalStorage/RBSegmentsCacheInLocal.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,10 @@ export class RBSegmentsCacheInLocal implements IRBSegmentsCacheSync {
105105
return item && JSON.parse(item);
106106
}
107107

108+
getAll(): IRBSegment[] {
109+
return this.getNames().map(key => this.get(key)!);
110+
}
111+
108112
contains(names: Set<string>): boolean {
109113
const namesArray = setToArray(names);
110114
const namesInStorage = this.getNames();

src/storages/inMemory/RBSegmentsCacheInMemory.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ export class RBSegmentsCacheInMemory implements IRBSegmentsCacheSync {
5151
return this.cache[name] || null;
5252
}
5353

54+
getAll(): IRBSegment[] {
55+
return this.getNames().map(key => this.get(key)!);
56+
}
57+
5458
contains(names: Set<string>): boolean {
5559
const namesArray = setToArray(names);
5660
const namesInStorage = this.getNames();

src/storages/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ export interface IRBSegmentsCacheSync extends IRBSegmentsCacheBase {
235235
update(toAdd: IRBSegment[], toRemove: IRBSegment[], changeNumber: number): boolean,
236236
get(name: string): IRBSegment | null,
237237
getChangeNumber(): number,
238+
getAll(): IRBSegment[],
238239
clear(): void,
239240
contains(names: Set<string>): boolean,
240241
// Used only for smart pausing in client-side standalone. Returns true if the storage contains a RBSegment using segments or large segments matchers

types/splitio.d.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,14 +1031,17 @@ declare namespace SplitIO {
10311031
*/
10321032
type PreloadedData = {
10331033
/**
1034-
* Change number of the preloaded data.
1035-
* If this value is older than the current changeNumber at the storage, the data is not used to update the storage content.
1034+
* Change number of feature flags.
10361035
*/
10371036
since: number;
10381037
/**
10391038
* List of feature flags.
10401039
*/
10411040
flags: Object[],
1041+
/**
1042+
* Change number of rule-based segments.
1043+
*/
1044+
rbSince?: number,
10421045
/**
10431046
* List of rule-based segments.
10441047
*/

0 commit comments

Comments
 (0)