@splitsoftware/splitio-commons 1.16.1-rc.11 → 1.16.1-rc.12

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.
Files changed (49) hide show
  1. package/cjs/logger/constants.js +2 -2
  2. package/cjs/logger/messages/warn.js +1 -1
  3. package/cjs/services/splitApi.js +2 -2
  4. package/cjs/storages/inMemory/TelemetryCacheInMemory.js +1 -1
  5. package/cjs/sync/polling/fetchers/mySegmentsFetcher.js +2 -2
  6. package/cjs/sync/polling/updaters/mySegmentsUpdater.js +6 -5
  7. package/cjs/sync/streaming/SSEHandler/index.js +2 -2
  8. package/cjs/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +104 -63
  9. package/cjs/sync/streaming/constants.js +3 -3
  10. package/cjs/sync/streaming/pushManager.js +17 -20
  11. package/esm/logger/constants.js +1 -1
  12. package/esm/logger/messages/warn.js +1 -1
  13. package/esm/services/splitApi.js +2 -2
  14. package/esm/storages/inMemory/TelemetryCacheInMemory.js +1 -1
  15. package/esm/sync/polling/fetchers/mySegmentsFetcher.js +2 -2
  16. package/esm/sync/polling/updaters/mySegmentsUpdater.js +7 -6
  17. package/esm/sync/streaming/SSEHandler/index.js +3 -3
  18. package/esm/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +104 -63
  19. package/esm/sync/streaming/constants.js +2 -2
  20. package/esm/sync/streaming/pushManager.js +19 -22
  21. package/package.json +1 -1
  22. package/src/logger/constants.ts +1 -1
  23. package/src/logger/messages/warn.ts +1 -1
  24. package/src/services/splitApi.ts +2 -2
  25. package/src/services/types.ts +1 -1
  26. package/src/storages/inMemory/TelemetryCacheInMemory.ts +1 -1
  27. package/src/storages/types.ts +1 -1
  28. package/src/sync/polling/fetchers/mySegmentsFetcher.ts +2 -1
  29. package/src/sync/polling/fetchers/types.ts +1 -0
  30. package/src/sync/polling/types.ts +3 -3
  31. package/src/sync/polling/updaters/mySegmentsUpdater.ts +8 -7
  32. package/src/sync/streaming/SSEHandler/index.ts +3 -3
  33. package/src/sync/streaming/SSEHandler/types.ts +3 -3
  34. package/src/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.ts +112 -64
  35. package/src/sync/streaming/constants.ts +2 -2
  36. package/src/sync/streaming/pushManager.ts +19 -25
  37. package/src/sync/streaming/types.ts +5 -5
  38. package/src/sync/submitters/types.ts +1 -1
  39. package/types/logger/constants.d.ts +1 -1
  40. package/types/services/types.d.ts +1 -1
  41. package/types/storages/types.d.ts +1 -1
  42. package/types/sync/polling/fetchers/types.d.ts +1 -1
  43. package/types/sync/polling/types.d.ts +3 -3
  44. package/types/sync/polling/updaters/mySegmentsUpdater.d.ts +1 -1
  45. package/types/sync/streaming/SSEHandler/types.d.ts +3 -3
  46. package/types/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.d.ts +3 -1
  47. package/types/sync/streaming/constants.d.ts +2 -2
  48. package/types/sync/streaming/types.d.ts +4 -4
  49. package/types/sync/submitters/types.d.ts +1 -1
@@ -3,81 +3,129 @@ import { Backoff } from '../../../utils/Backoff';
3
3
  import { IUpdateWorker } from './types';
4
4
  import { ITelemetryTracker } from '../../../trackers/types';
5
5
  import { MEMBERSHIPS } from '../../../utils/constants';
6
+ import { ISegmentsCacheSync, IStorageSync } from '../../../storages/types';
7
+ import { ILogger } from '../../../logger/types';
8
+ import { FETCH_BACKOFF_MAX_RETRIES } from './constants';
9
+ import { MEMBERSHIPS_LS_UPDATE, MEMBERSHIPS_MS_UPDATE } from '../constants';
6
10
 
7
11
  /**
8
12
  * MySegmentsUpdateWorker factory
9
13
  */
10
- export function MySegmentsUpdateWorker(mySegmentsSyncTask: IMySegmentsSyncTask, telemetryTracker: ITelemetryTracker): IUpdateWorker<[mySegmentsData?: Pick<MySegmentsData, 'type' | 'cn'>, payload?: Pick<MySegmentsData, 'added' | 'removed'>, delay?: number]> {
11
-
12
- let maxChangeNumber = 0; // keeps the maximum changeNumber among queued events
13
- let currentChangeNumber = -1;
14
- let handleNewEvent = false;
15
- let isHandlingEvent: boolean;
16
- let _segmentsData: MySegmentsData | undefined; // keeps the segmentsData (if included in notification payload) from the queued event with maximum changeNumber
17
- let _delay: undefined | number;
18
- let _delayTimeoutID: any;
19
- const backoff = new Backoff(__handleMySegmentsUpdateCall);
20
-
21
- function __handleMySegmentsUpdateCall() {
22
- isHandlingEvent = true;
23
- if (maxChangeNumber > currentChangeNumber) {
24
- handleNewEvent = false;
25
- const currentMaxChangeNumber = maxChangeNumber;
26
-
27
- // fetch mySegments revalidating data if cached
28
- const syncTask = _delay ?
29
- new Promise(res => {
30
- _delayTimeoutID = setTimeout(() => {
31
- _delay = undefined;
32
- mySegmentsSyncTask.execute(_segmentsData, true).then(res);
33
- }, _delay);
34
- }) :
35
- mySegmentsSyncTask.execute(_segmentsData, true);
36
-
37
- syncTask.then((result) => {
38
- if (!isHandlingEvent) return; // halt if `stop` has been called
39
- if (result !== false) { // Unlike `Splits|SegmentsUpdateWorker`, we cannot use `mySegmentsCache.getChangeNumber` since `/mySegments` endpoint doesn't provide this value.
40
- if (_segmentsData) telemetryTracker.trackUpdatesFromSSE(MEMBERSHIPS);
41
- currentChangeNumber = Math.max(currentChangeNumber, currentMaxChangeNumber); // use `currentMaxChangeNumber`, in case that `maxChangeNumber` was updated during fetch.
42
- }
43
- if (handleNewEvent) {
44
- __handleMySegmentsUpdateCall();
45
- } else {
46
- backoff.scheduleCall();
47
- }
48
- });
49
- } else {
50
- isHandlingEvent = false;
14
+ export function MySegmentsUpdateWorker(log: ILogger, storage: Pick<IStorageSync, 'segments' | 'largeSegments'>, mySegmentsSyncTask: IMySegmentsSyncTask, telemetryTracker: ITelemetryTracker): IUpdateWorker<[mySegmentsData?: Pick<MySegmentsData, 'type' | 'cn'>, payload?: Pick<MySegmentsData, 'added' | 'removed'>, delay?: number]> {
15
+
16
+ function createUpdateWorker(mySegmentsCache: ISegmentsCacheSync) {
17
+
18
+ let maxChangeNumber = 0; // keeps the maximum changeNumber among queued events
19
+ let currentChangeNumber = -1;
20
+ let handleNewEvent = false;
21
+ let isHandlingEvent: boolean;
22
+ let cdnBypass: boolean;
23
+ let _segmentsData: MySegmentsData | undefined; // keeps the segmentsData (if included in notification payload) from the queued event with maximum changeNumber
24
+ let _delay: undefined | number;
25
+ let _delayTimeoutID: any;
26
+ const backoff = new Backoff(__handleMySegmentsUpdateCall);
27
+
28
+ function __handleMySegmentsUpdateCall() {
29
+ isHandlingEvent = true;
30
+ if (maxChangeNumber > Math.max(currentChangeNumber, mySegmentsCache.getChangeNumber())) {
31
+ handleNewEvent = false;
32
+ const currentMaxChangeNumber = maxChangeNumber;
33
+
34
+ // fetch mySegments revalidating data if cached
35
+ const syncTask = _delay ?
36
+ new Promise(res => {
37
+ _delayTimeoutID = setTimeout(() => {
38
+ _delay = undefined;
39
+ mySegmentsSyncTask.execute(_segmentsData, true, cdnBypass ? maxChangeNumber : undefined).then(res);
40
+ }, _delay);
41
+ }) :
42
+ mySegmentsSyncTask.execute(_segmentsData, true, cdnBypass ? maxChangeNumber : undefined);
43
+
44
+ syncTask.then((result) => {
45
+ if (!isHandlingEvent) return; // halt if `stop` has been called
46
+ if (result !== false) { // Unlike `Splits|SegmentsUpdateWorker`, `mySegmentsCache.getChangeNumber` can be -1, since `/memberships` change number is optional
47
+ const storageChangeNumber = mySegmentsCache.getChangeNumber();
48
+ currentChangeNumber = storageChangeNumber > -1 ?
49
+ storageChangeNumber :
50
+ Math.max(currentChangeNumber, currentMaxChangeNumber); // use `currentMaxChangeNumber`, in case that `maxChangeNumber` was updated during fetch.
51
+ }
52
+ if (handleNewEvent) {
53
+ __handleMySegmentsUpdateCall();
54
+ } else {
55
+ if (_segmentsData) telemetryTracker.trackUpdatesFromSSE(MEMBERSHIPS);
56
+
57
+ const attempts = backoff.attempts + 1;
58
+
59
+ if (maxChangeNumber <= currentChangeNumber) {
60
+ log.debug(`Refresh completed${cdnBypass ? ' bypassing the CDN' : ''} in ${attempts} attempts.`);
61
+ isHandlingEvent = false;
62
+ return;
63
+ }
64
+
65
+ if (attempts < FETCH_BACKOFF_MAX_RETRIES) {
66
+ backoff.scheduleCall();
67
+ return;
68
+ }
69
+
70
+ if (cdnBypass) {
71
+ log.debug(`No changes fetched after ${attempts} attempts with CDN bypassed.`);
72
+ isHandlingEvent = false;
73
+ } else {
74
+ backoff.reset();
75
+ cdnBypass = true;
76
+ __handleMySegmentsUpdateCall();
77
+ }
78
+ }
79
+ });
80
+ } else {
81
+ isHandlingEvent = false;
82
+ }
51
83
  }
84
+
85
+ return {
86
+ /**
87
+ * Invoked by NotificationProcessor on MY_(LARGE)_SEGMENTS_UPDATE notifications
88
+ *
89
+ * @param changeNumber change number of the notification
90
+ * @param segmentsData data for KeyList or SegmentRemoval instant updates
91
+ * @param delay optional time to wait for BoundedFetchRequest or BoundedFetchRequest updates
92
+ */
93
+ put(mySegmentsData: Pick<MySegmentsData, 'type' | 'cn'>, payload?: Pick<MySegmentsData, 'added' | 'removed'>, delay?: number) {
94
+ const { type, cn } = mySegmentsData;
95
+ // Ignore event if it is outdated or if there is a pending fetch request (_delay is set)
96
+ if (cn <= Math.max(currentChangeNumber, mySegmentsCache.getChangeNumber()) || cn <= maxChangeNumber || _delay) return;
97
+
98
+ maxChangeNumber = cn;
99
+ handleNewEvent = true;
100
+ cdnBypass = false;
101
+ _segmentsData = payload && { type, cn, added: payload.added, removed: payload.removed };
102
+ _delay = delay;
103
+
104
+ if (backoff.timeoutID || !isHandlingEvent) __handleMySegmentsUpdateCall();
105
+ backoff.reset();
106
+ },
107
+
108
+ stop() {
109
+ clearTimeout(_delayTimeoutID);
110
+ _delay = undefined;
111
+ isHandlingEvent = false;
112
+ backoff.reset();
113
+ }
114
+ };
52
115
  }
53
116
 
117
+ const updateWorkers = {
118
+ [MEMBERSHIPS_MS_UPDATE]: createUpdateWorker(storage.segments),
119
+ [MEMBERSHIPS_LS_UPDATE]: createUpdateWorker(storage.largeSegments!),
120
+ };
121
+
54
122
  return {
55
- /**
56
- * Invoked by NotificationProcessor on MY_(LARGE)_SEGMENTS_UPDATE notifications
57
- *
58
- * @param changeNumber change number of the notification
59
- * @param segmentsData data for KeyList or SegmentRemoval instant updates
60
- * @param delay optional time to wait for BoundedFetchRequest or BoundedFetchRequest updates
61
- */
62
123
  put(mySegmentsData: Pick<MySegmentsData, 'type' | 'cn'>, payload?: Pick<MySegmentsData, 'added' | 'removed'>, delay?: number) {
63
- const { type, cn } = mySegmentsData;
64
- // Ignore event if it is outdated or if there is a pending fetch request (_delay is set)
65
- if (cn <= currentChangeNumber || cn <= maxChangeNumber || _delay) return;
66
-
67
- maxChangeNumber = cn;
68
- handleNewEvent = true;
69
- _segmentsData = payload && { type, cn, added: payload.added, removed: payload.removed };
70
- _delay = delay;
71
-
72
- if (backoff.timeoutID || !isHandlingEvent) __handleMySegmentsUpdateCall();
73
- backoff.reset();
124
+ updateWorkers[mySegmentsData.type].put(mySegmentsData, payload, delay);
74
125
  },
75
-
76
126
  stop() {
77
- clearTimeout(_delayTimeoutID);
78
- _delay = undefined;
79
- isHandlingEvent = false;
80
- backoff.reset();
127
+ updateWorkers[MEMBERSHIPS_MS_UPDATE].stop();
128
+ updateWorkers[MEMBERSHIPS_LS_UPDATE].stop();
81
129
  }
82
130
  };
83
131
  }
@@ -25,8 +25,8 @@ export const PUSH_SUBSYSTEM_UP = 'PUSH_SUBSYSTEM_UP';
25
25
  export const PUSH_SUBSYSTEM_DOWN = 'PUSH_SUBSYSTEM_DOWN';
26
26
 
27
27
  // Update-type push notifications, handled by NotificationProcessor
28
- export const MEMBERSHIP_MS_UPDATE = 'MEMBERSHIP_MS_UPDATE';
29
- export const MEMBERSHIP_LS_UPDATE = 'MEMBERSHIP_LS_UPDATE';
28
+ export const MEMBERSHIPS_MS_UPDATE = 'MEMBERSHIPS_MS_UPDATE';
29
+ export const MEMBERSHIPS_LS_UPDATE = 'MEMBERSHIPS_LS_UPDATE';
30
30
  export const SEGMENT_UPDATE = 'SEGMENT_UPDATE';
31
31
  export const SPLIT_KILL = 'SPLIT_KILL';
32
32
  export const SPLIT_UPDATE = 'SPLIT_UPDATE';
@@ -11,8 +11,8 @@ import { authenticateFactory, hashUserKey } from './AuthClient';
11
11
  import { forOwn } from '../../utils/lang';
12
12
  import { SSEClient } from './SSEClient';
13
13
  import { getMatching } from '../../utils/key';
14
- import { MEMBERSHIP_MS_UPDATE, MEMBERSHIP_LS_UPDATE, PUSH_NONRETRYABLE_ERROR, PUSH_SUBSYSTEM_DOWN, SECONDS_BEFORE_EXPIRATION, SEGMENT_UPDATE, SPLIT_KILL, SPLIT_UPDATE, PUSH_RETRYABLE_ERROR, PUSH_SUBSYSTEM_UP, ControlType } from './constants';
15
- import { STREAMING_FALLBACK, STREAMING_REFRESH_TOKEN, STREAMING_CONNECTING, STREAMING_DISABLED, ERROR_STREAMING_AUTH, STREAMING_DISCONNECTING, STREAMING_RECONNECT, STREAMING_PARSING_MEMBERSHIP_UPDATE, STREAMING_PARSING_SPLIT_UPDATE } from '../../logger/constants';
14
+ import { MEMBERSHIPS_MS_UPDATE, MEMBERSHIPS_LS_UPDATE, PUSH_NONRETRYABLE_ERROR, PUSH_SUBSYSTEM_DOWN, SECONDS_BEFORE_EXPIRATION, SEGMENT_UPDATE, SPLIT_KILL, SPLIT_UPDATE, PUSH_RETRYABLE_ERROR, PUSH_SUBSYSTEM_UP, ControlType } from './constants';
15
+ import { STREAMING_FALLBACK, STREAMING_REFRESH_TOKEN, STREAMING_CONNECTING, STREAMING_DISABLED, ERROR_STREAMING_AUTH, STREAMING_DISCONNECTING, STREAMING_RECONNECT, STREAMING_PARSING_MEMBERSHIPS_UPDATE, STREAMING_PARSING_SPLIT_UPDATE } from '../../logger/constants';
16
16
  import { IMembershipMSUpdateData, IMembershipLSUpdateData, KeyList, UpdateStrategy } from './SSEHandler/types';
17
17
  import { getDelay, isInBitmap, parseBitmap, parseFFUpdatePayload, parseKeyList } from './parseUtils';
18
18
  import { ISet, _Set } from '../../utils/lang/sets';
@@ -63,7 +63,7 @@ export function pushManagerFactory(
63
63
  const userKeyHashes: Record<string, string> = {};
64
64
  // [Only for client-side] map of user keys to their corresponding hash64 and MySegmentsUpdateWorkers.
65
65
  // Hash64 is used to process membership update events and dispatch actions to the corresponding MySegmentsUpdateWorker.
66
- const clients: Record<string, { hash64: Hash64, worker: ReturnType<typeof MySegmentsUpdateWorker>, workerLarge: ReturnType<typeof MySegmentsUpdateWorker> }> = {};
66
+ const clients: Record<string, { hash64: Hash64, worker: ReturnType<typeof MySegmentsUpdateWorker> }> = {};
67
67
 
68
68
  // [Only for client-side] variable to flag that a new client was added. It is needed to reconnect streaming.
69
69
  let connectForNewClient = false;
@@ -170,10 +170,7 @@ export function pushManagerFactory(
170
170
  // cancel scheduled fetch retries of Splits, Segments, and MySegments Update Workers
171
171
  function stopWorkers() {
172
172
  splitsUpdateWorker.stop();
173
- if (userKey) forOwn(clients, ({ worker, workerLarge }) => {
174
- worker.stop();
175
- workerLarge.stop();
176
- });
173
+ if (userKey) forOwn(clients, ({ worker }) => worker.stop());
177
174
  else segmentsUpdateWorker!.stop();
178
175
  }
179
176
 
@@ -239,21 +236,19 @@ export function pushManagerFactory(
239
236
  });
240
237
 
241
238
  function handleMySegmentsUpdate(parsedData: IMembershipMSUpdateData | IMembershipLSUpdateData) {
242
- const isLS = parsedData.type === MEMBERSHIP_LS_UPDATE;
243
-
244
239
  switch (parsedData.u) {
245
240
  case UpdateStrategy.BoundedFetchRequest: {
246
241
  let bitmap: Uint8Array;
247
242
  try {
248
243
  bitmap = parseBitmap(parsedData.d!, parsedData.c!);
249
244
  } catch (e) {
250
- log.warn(STREAMING_PARSING_MEMBERSHIP_UPDATE, ['BoundedFetchRequest', e]);
245
+ log.warn(STREAMING_PARSING_MEMBERSHIPS_UPDATE, ['BoundedFetchRequest', e]);
251
246
  break;
252
247
  }
253
248
 
254
- forOwn(clients, ({ hash64, worker, workerLarge }, matchingKey) => {
249
+ forOwn(clients, ({ hash64, worker }, matchingKey) => {
255
250
  if (isInBitmap(bitmap, hash64.hex)) {
256
- (isLS ? workerLarge : worker).put(parsedData, undefined, getDelay(parsedData, matchingKey));
251
+ worker.put(parsedData, undefined, getDelay(parsedData, matchingKey));
257
252
  }
258
253
  });
259
254
  return;
@@ -265,19 +260,19 @@ export function pushManagerFactory(
265
260
  added = new _Set(keyList.a);
266
261
  removed = new _Set(keyList.r);
267
262
  } catch (e) {
268
- log.warn(STREAMING_PARSING_MEMBERSHIP_UPDATE, ['KeyList', e]);
263
+ log.warn(STREAMING_PARSING_MEMBERSHIPS_UPDATE, ['KeyList', e]);
269
264
  break;
270
265
  }
271
266
 
272
267
  if (!parsedData.n || !parsedData.n.length) {
273
- log.warn(STREAMING_PARSING_MEMBERSHIP_UPDATE, ['KeyList', 'No segment name was provided']);
268
+ log.warn(STREAMING_PARSING_MEMBERSHIPS_UPDATE, ['KeyList', 'No segment name was provided']);
274
269
  break;
275
270
  }
276
271
 
277
- forOwn(clients, ({ hash64, worker, workerLarge }) => {
272
+ forOwn(clients, ({ hash64, worker }) => {
278
273
  const add = added.has(hash64.dec) ? true : removed.has(hash64.dec) ? false : undefined;
279
274
  if (add !== undefined) {
280
- (isLS ? workerLarge : worker).put(parsedData, {
275
+ worker.put(parsedData, {
281
276
  added: add ? [parsedData.n![0]] : [],
282
277
  removed: add ? [] : [parsedData.n![0]]
283
278
  });
@@ -287,12 +282,12 @@ export function pushManagerFactory(
287
282
  }
288
283
  case UpdateStrategy.SegmentRemoval:
289
284
  if (!parsedData.n || !parsedData.n.length) {
290
- log.warn(STREAMING_PARSING_MEMBERSHIP_UPDATE, ['SegmentRemoval', 'No segment name was provided']);
285
+ log.warn(STREAMING_PARSING_MEMBERSHIPS_UPDATE, ['SegmentRemoval', 'No segment name was provided']);
291
286
  break;
292
287
  }
293
288
 
294
- forOwn(clients, ({ worker, workerLarge }) => {
295
- (isLS ? workerLarge : worker).put(parsedData, {
289
+ forOwn(clients, ({ worker }) => {
290
+ worker.put(parsedData, {
296
291
  added: [],
297
292
  removed: parsedData.n!
298
293
  });
@@ -301,14 +296,14 @@ export function pushManagerFactory(
301
296
  }
302
297
 
303
298
  // `UpdateStrategy.UnboundedFetchRequest` and fallbacks of other cases
304
- forOwn(clients, ({ worker, workerLarge }, matchingKey) => {
305
- (isLS ? workerLarge : worker).put(parsedData, undefined, getDelay(parsedData, matchingKey));
299
+ forOwn(clients, ({ worker }, matchingKey) => {
300
+ worker.put(parsedData, undefined, getDelay(parsedData, matchingKey));
306
301
  });
307
302
  }
308
303
 
309
304
  if (userKey) {
310
- pushEmitter.on(MEMBERSHIP_MS_UPDATE, handleMySegmentsUpdate);
311
- pushEmitter.on(MEMBERSHIP_LS_UPDATE, handleMySegmentsUpdate);
305
+ pushEmitter.on(MEMBERSHIPS_MS_UPDATE, handleMySegmentsUpdate);
306
+ pushEmitter.on(MEMBERSHIPS_LS_UPDATE, handleMySegmentsUpdate);
312
307
  } else {
313
308
  pushEmitter.on(SEGMENT_UPDATE, segmentsUpdateWorker!.put);
314
309
  }
@@ -348,8 +343,7 @@ export function pushManagerFactory(
348
343
  userKeyHashes[hash] = userKey;
349
344
  clients[userKey] = {
350
345
  hash64: hash64(userKey),
351
- worker: MySegmentsUpdateWorker(mySegmentsSyncTask, telemetryTracker),
352
- workerLarge: MySegmentsUpdateWorker(mySegmentsSyncTask, telemetryTracker)
346
+ worker: MySegmentsUpdateWorker(log, storage, mySegmentsSyncTask, telemetryTracker)
353
347
  };
354
348
  connectForNewClient = true; // we must reconnect on start, to listen the channel for the new user key
355
349
 
@@ -11,8 +11,8 @@ export type PUSH_NONRETRYABLE_ERROR = 'PUSH_NONRETRYABLE_ERROR'
11
11
  export type PUSH_RETRYABLE_ERROR = 'PUSH_RETRYABLE_ERROR'
12
12
 
13
13
  // Update-type push notifications, handled by NotificationProcessor
14
- export type MEMBERSHIP_MS_UPDATE = 'MEMBERSHIP_MS_UPDATE';
15
- export type MEMBERSHIP_LS_UPDATE = 'MEMBERSHIP_LS_UPDATE';
14
+ export type MEMBERSHIPS_MS_UPDATE = 'MEMBERSHIPS_MS_UPDATE';
15
+ export type MEMBERSHIPS_LS_UPDATE = 'MEMBERSHIPS_LS_UPDATE';
16
16
  export type SEGMENT_UPDATE = 'SEGMENT_UPDATE';
17
17
  export type SPLIT_KILL = 'SPLIT_KILL';
18
18
  export type SPLIT_UPDATE = 'SPLIT_UPDATE';
@@ -21,11 +21,11 @@ export type SPLIT_UPDATE = 'SPLIT_UPDATE';
21
21
  export type CONTROL = 'CONTROL';
22
22
  export type OCCUPANCY = 'OCCUPANCY';
23
23
 
24
- export type IPushEvent = PUSH_SUBSYSTEM_UP | PUSH_SUBSYSTEM_DOWN | PUSH_NONRETRYABLE_ERROR | PUSH_RETRYABLE_ERROR | MEMBERSHIP_MS_UPDATE | MEMBERSHIP_LS_UPDATE | SEGMENT_UPDATE | SPLIT_UPDATE | SPLIT_KILL | ControlType.STREAMING_RESET
24
+ export type IPushEvent = PUSH_SUBSYSTEM_UP | PUSH_SUBSYSTEM_DOWN | PUSH_NONRETRYABLE_ERROR | PUSH_RETRYABLE_ERROR | MEMBERSHIPS_MS_UPDATE | MEMBERSHIPS_LS_UPDATE | SEGMENT_UPDATE | SPLIT_UPDATE | SPLIT_KILL | ControlType.STREAMING_RESET
25
25
 
26
26
  type IParsedData<T extends IPushEvent> =
27
- T extends MEMBERSHIP_MS_UPDATE ? IMembershipMSUpdateData :
28
- T extends MEMBERSHIP_LS_UPDATE ? IMembershipLSUpdateData :
27
+ T extends MEMBERSHIPS_MS_UPDATE ? IMembershipMSUpdateData :
28
+ T extends MEMBERSHIPS_LS_UPDATE ? IMembershipLSUpdateData :
29
29
  T extends SEGMENT_UPDATE ? ISegmentUpdateData :
30
30
  T extends SPLIT_UPDATE ? ISplitUpdateData :
31
31
  T extends SPLIT_KILL ? ISplitKillData : INotificationData;
@@ -176,7 +176,7 @@ export type TelemetryUsageStatsPayload = TelemetryUsageStats & {
176
176
  spC?: number, // splitCount
177
177
  seC?: number, // segmentCount
178
178
  skC?: number, // segmentKeyCount
179
- lseC?: number, // largeSegmentCount
179
+ lsC?: number, // largeSegmentCount
180
180
  lskC?: number, // largeSegmentKeyCount
181
181
  sL?: number, // sessionLengthMs
182
182
  eQ: number, // eventsQueued
@@ -77,7 +77,7 @@ export declare const WARN_SPLITS_FILTER_IGNORED = 219;
77
77
  export declare const WARN_SPLITS_FILTER_INVALID = 220;
78
78
  export declare const WARN_SPLITS_FILTER_EMPTY = 221;
79
79
  export declare const WARN_SDK_KEY = 222;
80
- export declare const STREAMING_PARSING_MEMBERSHIP_UPDATE = 223;
80
+ export declare const STREAMING_PARSING_MEMBERSHIPS_UPDATE = 223;
81
81
  export declare const STREAMING_PARSING_SPLIT_UPDATE = 224;
82
82
  export declare const WARN_INVALID_FLAGSET = 225;
83
83
  export declare const WARN_LOWERCASE_FLAGSET = 226;
@@ -18,7 +18,7 @@ export declare type ISplitHttpClient = (url: string, options?: IRequestOptions,
18
18
  export declare type IFetchAuth = (userKeys?: string[]) => Promise<IResponse>;
19
19
  export declare type IFetchSplitChanges = (since: number, noCache?: boolean, till?: number) => Promise<IResponse>;
20
20
  export declare type IFetchSegmentChanges = (since: number, segmentName: string, noCache?: boolean, till?: number) => Promise<IResponse>;
21
- export declare type IFetchMemberships = (userMatchingKey: string, noCache?: boolean) => Promise<IResponse>;
21
+ export declare type IFetchMemberships = (userMatchingKey: string, noCache?: boolean, till?: number) => Promise<IResponse>;
22
22
  export declare type IPostEventsBulk = (body: string, headers?: Record<string, string>) => Promise<IResponse>;
23
23
  export declare type IPostUniqueKeysBulkCs = (body: string, headers?: Record<string, string>) => Promise<IResponse>;
24
24
  export declare type IPostUniqueKeysBulkSs = (body: string, headers?: Record<string, string>) => Promise<IResponse>;
@@ -247,7 +247,7 @@ export interface ISegmentsCacheSync extends ISegmentsCacheBase {
247
247
  getRegisteredSegments(): string[];
248
248
  getKeysCount(): number;
249
249
  setChangeNumber(name: string, changeNumber: number): boolean | void;
250
- getChangeNumber(name: string): number;
250
+ getChangeNumber(name?: string): number;
251
251
  resetSegments(segmentsData: MySegmentsData | IMySegmentsResponse): boolean;
252
252
  clear(): void;
253
253
  }
@@ -2,4 +2,4 @@ import { ISplitChangesResponse, ISegmentChangesResponse, IMembershipsResponse }
2
2
  import { IResponse } from '../../../services/types';
3
3
  export declare type ISplitChangesFetcher = (since: number, noCache?: boolean, till?: number, decorator?: (promise: Promise<IResponse>) => Promise<IResponse>) => Promise<ISplitChangesResponse>;
4
4
  export declare type ISegmentChangesFetcher = (since: number, segmentName: string, noCache?: boolean, till?: number, decorator?: (promise: Promise<ISegmentChangesResponse[]>) => Promise<ISegmentChangesResponse[]>) => Promise<ISegmentChangesResponse[]>;
5
- export declare type IMySegmentsFetcher = (userMatchingKey: string, noCache?: boolean, decorator?: (promise: Promise<IResponse>) => Promise<IResponse>) => Promise<IMembershipsResponse>;
5
+ export declare type IMySegmentsFetcher = (userMatchingKey: string, noCache?: boolean, till?: number, decorator?: (promise: Promise<IResponse>) => Promise<IResponse>) => Promise<IMembershipsResponse>;
@@ -1,7 +1,7 @@
1
1
  import { ISplit } from '../../dtos/types';
2
2
  import { IReadinessManager } from '../../readiness/types';
3
3
  import { IStorageSync } from '../../storages/types';
4
- import { MEMBERSHIP_LS_UPDATE, MEMBERSHIP_MS_UPDATE } from '../streaming/types';
4
+ import { MEMBERSHIPS_LS_UPDATE, MEMBERSHIPS_MS_UPDATE } from '../streaming/types';
5
5
  import { ITask, ISyncTask } from '../types';
6
6
  export interface ISplitsSyncTask extends ISyncTask<[noCache?: boolean, till?: number, splitUpdateNotification?: {
7
7
  payload: ISplit;
@@ -11,12 +11,12 @@ export interface ISplitsSyncTask extends ISyncTask<[noCache?: boolean, till?: nu
11
11
  export interface ISegmentsSyncTask extends ISyncTask<[fetchOnlyNew?: boolean, segmentName?: string, noCache?: boolean, till?: number], boolean> {
12
12
  }
13
13
  export declare type MySegmentsData = {
14
- type: MEMBERSHIP_MS_UPDATE | MEMBERSHIP_LS_UPDATE;
14
+ type: MEMBERSHIPS_MS_UPDATE | MEMBERSHIPS_LS_UPDATE;
15
15
  cn: number;
16
16
  added: string[];
17
17
  removed: string[];
18
18
  };
19
- export interface IMySegmentsSyncTask extends ISyncTask<[segmentsData?: MySegmentsData, noCache?: boolean], boolean> {
19
+ export interface IMySegmentsSyncTask extends ISyncTask<[segmentsData?: MySegmentsData, noCache?: boolean, till?: number], boolean> {
20
20
  }
21
21
  export interface IPollingManager extends ITask {
22
22
  syncAll(): Promise<any>;
@@ -3,7 +3,7 @@ import { IStorageSync } from '../../../storages/types';
3
3
  import { ISegmentsEventEmitter } from '../../../readiness/types';
4
4
  import { ILogger } from '../../../logger/types';
5
5
  import { MySegmentsData } from '../types';
6
- declare type IMySegmentsUpdater = (segmentList?: MySegmentsData, noCache?: boolean) => Promise<boolean>;
6
+ declare type IMySegmentsUpdater = (segmentsData?: MySegmentsData, noCache?: boolean, till?: number) => Promise<boolean>;
7
7
  /**
8
8
  * factory of MySegments updater, a task that:
9
9
  * - fetches mySegments using `mySegmentsFetcher`
@@ -1,5 +1,5 @@
1
1
  import { ControlType } from '../constants';
2
- import { SEGMENT_UPDATE, SPLIT_UPDATE, SPLIT_KILL, CONTROL, OCCUPANCY, MEMBERSHIP_LS_UPDATE, MEMBERSHIP_MS_UPDATE } from '../types';
2
+ import { SEGMENT_UPDATE, SPLIT_UPDATE, SPLIT_KILL, CONTROL, OCCUPANCY, MEMBERSHIPS_LS_UPDATE, MEMBERSHIPS_MS_UPDATE } from '../types';
3
3
  export declare enum Compression {
4
4
  None = 0,
5
5
  Gzip = 1,
@@ -26,9 +26,9 @@ interface IMembershipUpdateData<T extends string> {
26
26
  h?: number;
27
27
  s?: number;
28
28
  }
29
- export interface IMembershipMSUpdateData extends IMembershipUpdateData<MEMBERSHIP_MS_UPDATE> {
29
+ export interface IMembershipMSUpdateData extends IMembershipUpdateData<MEMBERSHIPS_MS_UPDATE> {
30
30
  }
31
- export interface IMembershipLSUpdateData extends IMembershipUpdateData<MEMBERSHIP_LS_UPDATE> {
31
+ export interface IMembershipLSUpdateData extends IMembershipUpdateData<MEMBERSHIPS_LS_UPDATE> {
32
32
  }
33
33
  export interface ISegmentUpdateData {
34
34
  type: SEGMENT_UPDATE;
@@ -1,7 +1,9 @@
1
1
  import { IMySegmentsSyncTask, MySegmentsData } from '../../polling/types';
2
2
  import { IUpdateWorker } from './types';
3
3
  import { ITelemetryTracker } from '../../../trackers/types';
4
+ import { IStorageSync } from '../../../storages/types';
5
+ import { ILogger } from '../../../logger/types';
4
6
  /**
5
7
  * MySegmentsUpdateWorker factory
6
8
  */
7
- export declare function MySegmentsUpdateWorker(mySegmentsSyncTask: IMySegmentsSyncTask, telemetryTracker: ITelemetryTracker): IUpdateWorker<[mySegmentsData?: Pick<MySegmentsData, 'type' | 'cn'>, payload?: Pick<MySegmentsData, 'added' | 'removed'>, delay?: number]>;
9
+ export declare function MySegmentsUpdateWorker(log: ILogger, storage: Pick<IStorageSync, 'segments' | 'largeSegments'>, mySegmentsSyncTask: IMySegmentsSyncTask, telemetryTracker: ITelemetryTracker): IUpdateWorker<[mySegmentsData?: Pick<MySegmentsData, 'type' | 'cn'>, payload?: Pick<MySegmentsData, 'added' | 'removed'>, delay?: number]>;
@@ -19,8 +19,8 @@ export declare const PUSH_SUBSYSTEM_UP = "PUSH_SUBSYSTEM_UP";
19
19
  * triggers `startPolling` and `stopWorkers` calls
20
20
  */
21
21
  export declare const PUSH_SUBSYSTEM_DOWN = "PUSH_SUBSYSTEM_DOWN";
22
- export declare const MEMBERSHIP_MS_UPDATE = "MEMBERSHIP_MS_UPDATE";
23
- export declare const MEMBERSHIP_LS_UPDATE = "MEMBERSHIP_LS_UPDATE";
22
+ export declare const MEMBERSHIPS_MS_UPDATE = "MEMBERSHIPS_MS_UPDATE";
23
+ export declare const MEMBERSHIPS_LS_UPDATE = "MEMBERSHIPS_LS_UPDATE";
24
24
  export declare const SEGMENT_UPDATE = "SEGMENT_UPDATE";
25
25
  export declare const SPLIT_KILL = "SPLIT_KILL";
26
26
  export declare const SPLIT_UPDATE = "SPLIT_UPDATE";
@@ -7,15 +7,15 @@ export declare type PUSH_SUBSYSTEM_UP = 'PUSH_SUBSYSTEM_UP';
7
7
  export declare type PUSH_SUBSYSTEM_DOWN = 'PUSH_SUBSYSTEM_DOWN';
8
8
  export declare type PUSH_NONRETRYABLE_ERROR = 'PUSH_NONRETRYABLE_ERROR';
9
9
  export declare type PUSH_RETRYABLE_ERROR = 'PUSH_RETRYABLE_ERROR';
10
- export declare type MEMBERSHIP_MS_UPDATE = 'MEMBERSHIP_MS_UPDATE';
11
- export declare type MEMBERSHIP_LS_UPDATE = 'MEMBERSHIP_LS_UPDATE';
10
+ export declare type MEMBERSHIPS_MS_UPDATE = 'MEMBERSHIPS_MS_UPDATE';
11
+ export declare type MEMBERSHIPS_LS_UPDATE = 'MEMBERSHIPS_LS_UPDATE';
12
12
  export declare type SEGMENT_UPDATE = 'SEGMENT_UPDATE';
13
13
  export declare type SPLIT_KILL = 'SPLIT_KILL';
14
14
  export declare type SPLIT_UPDATE = 'SPLIT_UPDATE';
15
15
  export declare type CONTROL = 'CONTROL';
16
16
  export declare type OCCUPANCY = 'OCCUPANCY';
17
- export declare type IPushEvent = PUSH_SUBSYSTEM_UP | PUSH_SUBSYSTEM_DOWN | PUSH_NONRETRYABLE_ERROR | PUSH_RETRYABLE_ERROR | MEMBERSHIP_MS_UPDATE | MEMBERSHIP_LS_UPDATE | SEGMENT_UPDATE | SPLIT_UPDATE | SPLIT_KILL | ControlType.STREAMING_RESET;
18
- declare type IParsedData<T extends IPushEvent> = T extends MEMBERSHIP_MS_UPDATE ? IMembershipMSUpdateData : T extends MEMBERSHIP_LS_UPDATE ? IMembershipLSUpdateData : T extends SEGMENT_UPDATE ? ISegmentUpdateData : T extends SPLIT_UPDATE ? ISplitUpdateData : T extends SPLIT_KILL ? ISplitKillData : INotificationData;
17
+ export declare type IPushEvent = PUSH_SUBSYSTEM_UP | PUSH_SUBSYSTEM_DOWN | PUSH_NONRETRYABLE_ERROR | PUSH_RETRYABLE_ERROR | MEMBERSHIPS_MS_UPDATE | MEMBERSHIPS_LS_UPDATE | SEGMENT_UPDATE | SPLIT_UPDATE | SPLIT_KILL | ControlType.STREAMING_RESET;
18
+ declare type IParsedData<T extends IPushEvent> = T extends MEMBERSHIPS_MS_UPDATE ? IMembershipMSUpdateData : T extends MEMBERSHIPS_LS_UPDATE ? IMembershipLSUpdateData : T extends SEGMENT_UPDATE ? ISegmentUpdateData : T extends SPLIT_UPDATE ? ISplitUpdateData : T extends SPLIT_KILL ? ISplitKillData : INotificationData;
19
19
  /**
20
20
  * EventEmitter used as Feedback Loop between the SyncManager and PushManager,
21
21
  * where the latter pushes messages and the former consumes it
@@ -152,7 +152,7 @@ export declare type TelemetryUsageStatsPayload = TelemetryUsageStats & {
152
152
  spC?: number;
153
153
  seC?: number;
154
154
  skC?: number;
155
- lseC?: number;
155
+ lsC?: number;
156
156
  lskC?: number;
157
157
  sL?: number;
158
158
  eQ: number;