Skip to content

Commit f4a6988

Browse files
Update metadata properties
1 parent ef651cc commit f4a6988

File tree

10 files changed

+57
-28
lines changed

10 files changed

+57
-28
lines changed

src/readiness/__tests__/readinessManager.spec.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,8 @@ test('READINESS MANAGER / SDK_UPDATE should emit with metadata', () => {
310310
readinessManager.segments.emit(SDK_SEGMENTS_ARRIVED);
311311

312312
const metadata: SdkUpdateMetadata = {
313-
[SdkUpdateMetadataKeys.UPDATED_FLAGS]: ['flag1', 'flag2']
313+
type: SdkUpdateMetadataKeys.FLAGS_UPDATE,
314+
names: ['flag1', 'flag2']
314315
};
315316

316317
let receivedMetadata: SdkUpdateMetadata | undefined;
@@ -348,7 +349,8 @@ test('READINESS MANAGER / SDK_UPDATE should forward metadata from segments', ()
348349
readinessManager.segments.emit(SDK_SEGMENTS_ARRIVED);
349350

350351
const metadata: SdkUpdateMetadata = {
351-
[SdkUpdateMetadataKeys.UPDATED_SEGMENTS]: ['segment1', 'segment2']
352+
type: SdkUpdateMetadataKeys.SEGMENTS_UPDATE,
353+
names: ['segment1', 'segment2']
352354
};
353355

354356
let receivedMetadata: SdkUpdateMetadata | undefined;

src/readiness/readinessManager.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { ISettings } from '../types';
33
import SplitIO from '../../types/splitio';
44
import { SDK_SPLITS_ARRIVED, SDK_SPLITS_CACHE_LOADED, SDK_SEGMENTS_ARRIVED, SDK_READY_TIMED_OUT, SDK_READY_FROM_CACHE, SDK_UPDATE, SDK_READY } from './constants';
55
import { IReadinessEventEmitter, IReadinessManager, ISegmentsEventEmitter, ISplitsEventEmitter } from './types';
6-
import { SdkUpdateMetadata } from '../sync/polling/types';
76

87
function splitsEventEmitterFactory(EventEmitter: new () => SplitIO.IEventEmitter): ISplitsEventEmitter {
98
const splitsEventEmitter = objectAssign(new EventEmitter(), {
@@ -16,7 +15,7 @@ function splitsEventEmitterFactory(EventEmitter: new () => SplitIO.IEventEmitter
1615
// `isSplitKill` condition avoids an edge-case of wrongly emitting SDK_READY if:
1716
// - `/memberships` fetch and SPLIT_KILL occurs before `/splitChanges` fetch, and
1817
// - storage has cached splits (for which case `splitsStorage.killLocally` can return true)
19-
splitsEventEmitter.on(SDK_SPLITS_ARRIVED, (metadata: SdkUpdateMetadata, isSplitKill: boolean) => { if (!isSplitKill) splitsEventEmitter.splitsArrived = true; });
18+
splitsEventEmitter.on(SDK_SPLITS_ARRIVED, (metadata: SplitIO.SdkUpdateMetadata, isSplitKill: boolean) => { if (!isSplitKill) splitsEventEmitter.splitsArrived = true; });
2019
splitsEventEmitter.once(SDK_SPLITS_CACHE_LOADED, () => { splitsEventEmitter.splitsCacheLoaded = true; });
2120

2221
return splitsEventEmitter;
@@ -99,7 +98,7 @@ export function readinessManagerFactory(
9998
}
10099
}
101100

102-
function checkIsReadyOrUpdate(metadata: SdkUpdateMetadata) {
101+
function checkIsReadyOrUpdate(metadata: SplitIO.SdkUpdateMetadata) {
103102
if (isDestroyed) return;
104103
if (isReady) {
105104
try {

src/readiness/types.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import SplitIO from '../../types/splitio';
2-
import { SdkUpdateMetadata } from '../sync/polling/types';
32

43
/** Readiness event types */
54

@@ -23,7 +22,7 @@ type ISplitsEvent = SDK_SPLITS_ARRIVED | SDK_SPLITS_CACHE_LOADED
2322
export interface ISplitsEventEmitter extends SplitIO.IEventEmitter {
2423
emit(event: ISplitsEvent, ...args: any[]): boolean
2524
on(event: ISplitsEvent, listener: (...args: any[]) => void): this;
26-
on(event: SDK_UPDATE, listener: (metadata: SdkUpdateMetadata) => void): this;
25+
on(event: SDK_UPDATE, listener: (metadata: SplitIO.SdkUpdateMetadata) => void): this;
2726
once(event: ISplitsEvent, listener: (...args: any[]) => void): this;
2827
splitsArrived: boolean
2928
splitsCacheLoaded: boolean
@@ -39,7 +38,7 @@ type ISegmentsEvent = SDK_SEGMENTS_ARRIVED
3938
export interface ISegmentsEventEmitter extends SplitIO.IEventEmitter {
4039
emit(event: ISegmentsEvent, ...args: any[]): boolean
4140
on(event: ISegmentsEvent, listener: (...args: any[]) => void): this;
42-
on(event: SDK_UPDATE, listener: (metadata: SdkUpdateMetadata) => void): this;
41+
on(event: SDK_UPDATE, listener: (metadata: SplitIO.SdkUpdateMetadata) => void): this;
4342
once(event: ISegmentsEvent, listener: (...args: any[]) => void): this;
4443
segmentsArrived: boolean
4544
}

src/sync/polling/types.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,13 @@ export interface IPollingManagerCS extends IPollingManager {
3333
}
3434

3535
export enum SdkUpdateMetadataKeys {
36-
UPDATED_FLAGS = 'updatedFlags',
37-
UPDATED_SEGMENTS = 'updatedSegments'
36+
FLAGS_UPDATE = 'FLAGS_UPDATE',
37+
SEGMENTS_UPDATE = 'SEGMENTS_UPDATE'
3838
}
39-
39+
/**
40+
* SdkUpdateMetadata type for polling updaters
41+
*/
4042
export type SdkUpdateMetadata = {
41-
[SdkUpdateMetadataKeys.UPDATED_FLAGS]?: string[]
42-
[SdkUpdateMetadataKeys.UPDATED_SEGMENTS]?: string[]
43+
type: SdkUpdateMetadataKeys.FLAGS_UPDATE | SdkUpdateMetadataKeys.SEGMENTS_UPDATE
44+
names: string[]
4345
}

src/sync/polling/updaters/__tests__/segmentChangesUpdater.spec.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { loggerMock } from '../../../../logger/__tests__/sdkLogger.mock';
77
import { ISegmentChangesFetcher } from '../../fetchers/types';
88
import { ISegmentChangesResponse } from '../../../../dtos/types';
99
import { SDK_SEGMENTS_ARRIVED } from '../../../../readiness/constants';
10+
import { SdkUpdateMetadataKeys } from '../../types';
1011

1112
describe('segmentChangesUpdater', () => {
1213
const segments = new SegmentsCacheInMemory();
@@ -47,6 +48,6 @@ describe('segmentChangesUpdater', () => {
4748
await segmentChangesUpdater(undefined, segmentName);
4849

4950
expect(updateSegments).toHaveBeenCalledWith(segmentName, segmentChange.added, segmentChange.removed, segmentChange.till);
50-
expect(segmentsEmitSpy).toBeCalledWith(SDK_SEGMENTS_ARRIVED, { updatedSegments: [segmentName] });
51+
expect(segmentsEmitSpy).toBeCalledWith(SDK_SEGMENTS_ARRIVED, { type: SdkUpdateMetadataKeys.SEGMENTS_UPDATE, names: [segmentName] });
5152
});
5253
});

src/sync/polling/updaters/__tests__/splitChangesUpdater.spec.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { RBSegmentsCacheInMemory } from '../../../../storages/inMemory/RBSegment
1616
import { RB_SEGMENT_UPDATE, SPLIT_UPDATE } from '../../../streaming/constants';
1717
import { IN_RULE_BASED_SEGMENT } from '../../../../utils/constants';
1818
import { SDK_SPLITS_ARRIVED } from '../../../../readiness/constants';
19+
import { SdkUpdateMetadataKeys } from '../../types';
1920

2021
const ARCHIVED_FF = 'ARCHIVED';
2122

@@ -221,7 +222,7 @@ describe('splitChangesUpdater', () => {
221222
expect(updateSplits).lastCalledWith(splitChangesMock1.ff.d, [], splitChangesMock1.ff.t);
222223
expect(updateRbSegments).toBeCalledTimes(0); // no rbSegments to update
223224
expect(registerSegments).toBeCalledTimes(1);
224-
expect(splitsEmitSpy).toBeCalledWith(SDK_SPLITS_ARRIVED, { updatedFlags });
225+
expect(splitsEmitSpy).toBeCalledWith(SDK_SPLITS_ARRIVED, { type: SdkUpdateMetadataKeys.FLAGS_UPDATE, names: updatedFlags });
225226
expect(result).toBe(true);
226227
});
227228

@@ -287,7 +288,7 @@ describe('splitChangesUpdater', () => {
287288
for (const setMock of setMocks) {
288289
await expect(splitChangesUpdater(undefined, undefined, { payload: { ...payload, sets: setMock.sets, status: 'ACTIVE' }, changeNumber: index, type: SPLIT_UPDATE })).resolves.toBe(true);
289290
expect(splitsEmitSpy.mock.calls[index][0]).toBe(SDK_SPLITS_ARRIVED);
290-
expect(splitsEmitSpy.mock.calls[index][1]).toEqual({ updatedFlags: [payload.name] });
291+
expect(splitsEmitSpy.mock.calls[index][1]).toEqual({ type: SdkUpdateMetadataKeys.FLAGS_UPDATE, names: [payload.name] });
291292
index++;
292293
}
293294

@@ -317,7 +318,7 @@ describe('splitChangesUpdater', () => {
317318

318319
await expect(splitChangesUpdater(undefined, undefined, { payload, changeNumber: changeNumber, type: SPLIT_UPDATE })).resolves.toBe(true);
319320

320-
expect(splitsEmitSpy).toBeCalledWith(SDK_SPLITS_ARRIVED, { updatedFlags: [payload.name] });
321+
expect(splitsEmitSpy).toBeCalledWith(SDK_SPLITS_ARRIVED, { type: SdkUpdateMetadataKeys.FLAGS_UPDATE, names: [payload.name] });
321322
});
322323

323324
});

src/sync/polling/updaters/segmentChangesUpdater.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import { SDK_SEGMENTS_ARRIVED } from '../../../readiness/constants';
55
import { ILogger } from '../../../logger/types';
66
import { LOG_PREFIX_INSTANTIATION, LOG_PREFIX_SYNC_SEGMENTS } from '../../../logger/constants';
77
import { timeout } from '../../../utils/promise/timeout';
8+
import { SdkUpdateMetadata, SdkUpdateMetadataKeys } from '../types';
9+
810

911
type ISegmentChangesUpdater = (fetchOnlyNew?: boolean, segmentName?: string, noCache?: boolean, till?: number) => Promise<boolean>
1012

@@ -83,7 +85,11 @@ export function segmentChangesUpdaterFactory(
8385
// if at least one segment fetch succeeded, mark segments ready
8486
if (shouldUpdateFlags.some(update => update) || readyOnAlreadyExistentState) {
8587
readyOnAlreadyExistentState = false;
86-
if (readiness) readiness.segments.emit(SDK_SEGMENTS_ARRIVED, { updatedSegments: segmentNames });
88+
const metadata: SdkUpdateMetadata = {
89+
type: SdkUpdateMetadataKeys.SEGMENTS_UPDATE,
90+
names: segmentNames
91+
};
92+
if (readiness) readiness.segments.emit(SDK_SEGMENTS_ARRIVED, metadata);
8793
}
8894
return true;
8995
});

src/sync/polling/updaters/splitChangesUpdater.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { startsWith } from '../../../utils/lang';
1010
import { IN_RULE_BASED_SEGMENT, IN_SEGMENT, RULE_BASED_SEGMENT, STANDARD_SEGMENT } from '../../../utils/constants';
1111
import { setToArray } from '../../../utils/lang/sets';
1212
import { SPLIT_UPDATE } from '../../streaming/constants';
13+
import { SdkUpdateMetadata, SdkUpdateMetadataKeys } from '../types';
1314

1415
export type InstantUpdate = { payload: ISplit | IRBSegment, changeNumber: number, type: string };
1516
type SplitChangesUpdater = (noCache?: boolean, till?: number, instantUpdate?: InstantUpdate) => Promise<boolean>
@@ -89,15 +90,14 @@ export function computeMutation<T extends ISplit | IRBSegment>(rules: Array<T>,
8990
return rules.reduce((accum, ruleEntity) => {
9091
if (ruleEntity.status === 'ACTIVE' && (!filters || matchFilters(ruleEntity as ISplit, filters))) {
9192
accum.added.push(ruleEntity);
92-
accum.names.push(ruleEntity.name);
9393

9494
parseSegments(ruleEntity).forEach((segmentName: string) => {
9595
segments.add(segmentName);
9696
});
9797
} else {
9898
accum.removed.push(ruleEntity);
99-
accum.names.push(ruleEntity.name);
10099
}
100+
accum.names.push(ruleEntity.name);
101101

102102
return accum;
103103
}, { added: [], removed: [], names: [] } as ISplitMutations<T>);
@@ -197,8 +197,12 @@ export function splitChangesUpdaterFactory(
197197
return Promise.resolve(!splitsEventEmitter.splitsArrived || ((ffChanged || rbsChanged) && (isClientSide || checkAllSegmentsExist(segments))))
198198
.catch(() => false /** noop. just to handle a possible `checkAllSegmentsExist` rejection, before emitting SDK event */)
199199
.then(emitSplitsArrivedEvent => {
200+
const metadata: SdkUpdateMetadata = {
201+
type: SdkUpdateMetadataKeys.FLAGS_UPDATE,
202+
names: updatedFlags
203+
};
200204
// emit SDK events
201-
if (emitSplitsArrivedEvent) splitsEventEmitter.emit(SDK_SPLITS_ARRIVED, { updatedFlags });
205+
if (emitSplitsArrivedEvent) splitsEventEmitter.emit(SDK_SPLITS_ARRIVED, metadata);
202206
return true;
203207
});
204208
}

src/sync/streaming/types.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import { IMembershipMSUpdateData, IMembershipLSUpdateData, ISegmentUpdateData, ISplitUpdateData, ISplitKillData, INotificationData } from './SSEHandler/types';
22
import { ITask } from '../types';
3-
import { IMySegmentsSyncTask, SdkUpdateMetadata } from '../polling/types';
3+
import { IMySegmentsSyncTask } from '../polling/types';
44
import SplitIO from '../../../types/splitio';
55
import { ControlType } from './constants';
6-
import { SDK_UPDATE } from '../../readiness/types';
76

87
// Internal SDK events, subscribed by SyncManager and PushManager
98
export type PUSH_SUBSYSTEM_UP = 'PUSH_SUBSYSTEM_UP'
@@ -38,7 +37,7 @@ type IParsedData<T extends IPushEvent> =
3837
*/
3938
export interface IPushEventEmitter extends SplitIO.IEventEmitter {
4039
once<T extends IPushEvent>(event: T, listener: (parsedData: IParsedData<T>) => void): this;
41-
on<T extends IPushEvent>(event: T, listener: (metadata: T extends SDK_UPDATE ? SdkUpdateMetadata : never) => void): this;
40+
on<T extends IPushEvent>(event: T, listener: (parsedData: IParsedData<T>) => void): this;
4241
emit<T extends IPushEvent>(event: T, parsedData?: IParsedData<T>): boolean;
4342
}
4443

types/splitio.d.ts

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33

44
import { RedisOptions } from 'ioredis';
55
import { RequestOptions } from 'http';
6-
import { SDK_UPDATE } from '../src/readiness/types';
7-
import { SdkUpdateMetadata } from '../src/sync/polling/types';
86

97
export as namespace SplitIO;
108
export = SplitIO;
@@ -494,12 +492,28 @@ declare namespace SplitIO {
494492
removeItem(key: string): void | Promise<void>;
495493
}
496494

495+
/**
496+
* Metadata keys for SDK update events.
497+
*/
498+
enum SdkUpdateMetadataKeys {
499+
FLAGS_UPDATE = 'FLAGS_UPDATE',
500+
SEGMENTS_UPDATE = 'SEGMENTS_UPDATE'
501+
}
502+
503+
/**
504+
* List of modified flags or segments
505+
* when a sdk update event is emitted.
506+
*/
507+
type SdkUpdateMetadata = {
508+
type: SdkUpdateMetadataKeys.FLAGS_UPDATE | SdkUpdateMetadataKeys.SEGMENTS_UPDATE
509+
names: string[]
510+
}
511+
497512
/**
498513
* EventEmitter interface based on a subset of the Node.js EventEmitter methods.
499514
*/
500515
interface IEventEmitter {
501516
addListener(event: string, listener: (...args: any[]) => void): this;
502-
on(event: SDK_UPDATE, listener: (metadata: SdkUpdateMetadata) => void): this;
503517
on(event: string, listener: (...args: any[]) => void): this;
504518
once(event: string, listener: (...args: any[]) => void): this;
505519
removeListener(event: string, listener: (...args: any[]) => void): this;
@@ -512,9 +526,11 @@ declare namespace SplitIO {
512526
* @see {@link https://nodejs.org/api/events.html}
513527
*/
514528
interface EventEmitter extends IEventEmitter {
529+
addListener(event: EventConsts['SDK_UPDATE'], listener: (metadata: SdkUpdateMetadata) => void): this;
515530
addListener(event: string | symbol, listener: (...args: any[]) => void): this;
516-
on(event: SDK_UPDATE, listener: (metadata: SdkUpdateMetadata) => void): this;
531+
on(event: EventConsts['SDK_UPDATE'], listener: (metadata: SdkUpdateMetadata) => void): this;
517532
on(event: string | symbol, listener: (...args: any[]) => void): this;
533+
once(event: EventConsts['SDK_UPDATE'], listener: (metadata: SdkUpdateMetadata) => void): this;
518534
once(event: string | symbol, listener: (...args: any[]) => void): this;
519535
removeListener(event: string | symbol, listener: (...args: any[]) => void): this;
520536
off(event: string | symbol, listener: (...args: any[]) => void): this;

0 commit comments

Comments
 (0)