@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.
- package/cjs/logger/constants.js +2 -2
- package/cjs/logger/messages/warn.js +1 -1
- package/cjs/services/splitApi.js +2 -2
- package/cjs/storages/inMemory/TelemetryCacheInMemory.js +1 -1
- package/cjs/sync/polling/fetchers/mySegmentsFetcher.js +2 -2
- package/cjs/sync/polling/updaters/mySegmentsUpdater.js +6 -5
- package/cjs/sync/streaming/SSEHandler/index.js +2 -2
- package/cjs/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +104 -63
- package/cjs/sync/streaming/constants.js +3 -3
- package/cjs/sync/streaming/pushManager.js +17 -20
- package/esm/logger/constants.js +1 -1
- package/esm/logger/messages/warn.js +1 -1
- package/esm/services/splitApi.js +2 -2
- package/esm/storages/inMemory/TelemetryCacheInMemory.js +1 -1
- package/esm/sync/polling/fetchers/mySegmentsFetcher.js +2 -2
- package/esm/sync/polling/updaters/mySegmentsUpdater.js +7 -6
- package/esm/sync/streaming/SSEHandler/index.js +3 -3
- package/esm/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +104 -63
- package/esm/sync/streaming/constants.js +2 -2
- package/esm/sync/streaming/pushManager.js +19 -22
- package/package.json +1 -1
- package/src/logger/constants.ts +1 -1
- package/src/logger/messages/warn.ts +1 -1
- package/src/services/splitApi.ts +2 -2
- package/src/services/types.ts +1 -1
- package/src/storages/inMemory/TelemetryCacheInMemory.ts +1 -1
- package/src/storages/types.ts +1 -1
- package/src/sync/polling/fetchers/mySegmentsFetcher.ts +2 -1
- package/src/sync/polling/fetchers/types.ts +1 -0
- package/src/sync/polling/types.ts +3 -3
- package/src/sync/polling/updaters/mySegmentsUpdater.ts +8 -7
- package/src/sync/streaming/SSEHandler/index.ts +3 -3
- package/src/sync/streaming/SSEHandler/types.ts +3 -3
- package/src/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.ts +112 -64
- package/src/sync/streaming/constants.ts +2 -2
- package/src/sync/streaming/pushManager.ts +19 -25
- package/src/sync/streaming/types.ts +5 -5
- package/src/sync/submitters/types.ts +1 -1
- package/types/logger/constants.d.ts +1 -1
- package/types/services/types.d.ts +1 -1
- package/types/storages/types.d.ts +1 -1
- package/types/sync/polling/fetchers/types.d.ts +1 -1
- package/types/sync/polling/types.d.ts +3 -3
- package/types/sync/polling/updaters/mySegmentsUpdater.d.ts +1 -1
- package/types/sync/streaming/SSEHandler/types.d.ts +3 -3
- package/types/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.d.ts +3 -1
- package/types/sync/streaming/constants.d.ts +2 -2
- package/types/sync/streaming/types.d.ts +4 -4
- 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
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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
|
-
|
|
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
|
-
|
|
78
|
-
|
|
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
|
|
29
|
-
export const
|
|
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 {
|
|
15
|
-
import { STREAMING_FALLBACK, STREAMING_REFRESH_TOKEN, STREAMING_CONNECTING, STREAMING_DISABLED, ERROR_STREAMING_AUTH, STREAMING_DISCONNECTING, STREAMING_RECONNECT,
|
|
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
|
|
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
|
|
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(
|
|
245
|
+
log.warn(STREAMING_PARSING_MEMBERSHIPS_UPDATE, ['BoundedFetchRequest', e]);
|
|
251
246
|
break;
|
|
252
247
|
}
|
|
253
248
|
|
|
254
|
-
forOwn(clients, ({ hash64, worker
|
|
249
|
+
forOwn(clients, ({ hash64, worker }, matchingKey) => {
|
|
255
250
|
if (isInBitmap(bitmap, hash64.hex)) {
|
|
256
|
-
|
|
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(
|
|
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(
|
|
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
|
|
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
|
-
|
|
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(
|
|
285
|
+
log.warn(STREAMING_PARSING_MEMBERSHIPS_UPDATE, ['SegmentRemoval', 'No segment name was provided']);
|
|
291
286
|
break;
|
|
292
287
|
}
|
|
293
288
|
|
|
294
|
-
forOwn(clients, ({ worker
|
|
295
|
-
|
|
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
|
|
305
|
-
|
|
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(
|
|
311
|
-
pushEmitter.on(
|
|
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
|
|
15
|
-
export type
|
|
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 |
|
|
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
|
|
28
|
-
T extends
|
|
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
|
-
|
|
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
|
|
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
|
|
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 {
|
|
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:
|
|
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 = (
|
|
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,
|
|
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<
|
|
29
|
+
export interface IMembershipMSUpdateData extends IMembershipUpdateData<MEMBERSHIPS_MS_UPDATE> {
|
|
30
30
|
}
|
|
31
|
-
export interface IMembershipLSUpdateData extends IMembershipUpdateData<
|
|
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
|
|
23
|
-
export declare const
|
|
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
|
|
11
|
-
export declare type
|
|
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 |
|
|
18
|
-
declare type IParsedData<T extends IPushEvent> = T extends
|
|
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
|