@splitsoftware/splitio-commons 0.1.1-canary.9 → 0.1.1-rc.18
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/evaluator/matchers/matcherTypes.js +4 -4
- package/cjs/evaluator/matchersTransform/index.js +11 -11
- package/cjs/evaluator/value/sanitize.js +6 -6
- package/cjs/listeners/browser.js +1 -2
- package/cjs/listeners/node.js +0 -3
- package/cjs/logger/constants.js +3 -1
- package/cjs/logger/messages/error.js +3 -2
- package/cjs/logger/messages/info.js +2 -2
- package/cjs/logger/messages/warn.js +2 -1
- package/cjs/readiness/readinessManager.js +10 -7
- package/cjs/sdkFactory/index.js +1 -4
- package/cjs/services/splitApi.js +1 -1
- package/cjs/services/splitHttpClient.js +5 -4
- package/cjs/storages/AbstractSplitsCacheSync.js +1 -1
- package/cjs/storages/inLocalStorage/index.js +5 -2
- package/cjs/storages/inMemory/InMemoryStorage.js +2 -0
- package/cjs/storages/inMemory/InMemoryStorageCS.js +2 -0
- package/cjs/storages/inRedis/SplitsCacheInRedis.js +6 -2
- package/cjs/storages/inRedis/index.js +5 -2
- package/cjs/storages/pluggable/SplitsCachePluggable.js +6 -2
- package/cjs/storages/pluggable/inMemoryWrapper.js +6 -7
- package/cjs/storages/pluggable/index.js +5 -2
- package/cjs/storages/pluggable/wrapperAdapter.js +0 -1
- package/cjs/sync/offline/splitsParser/splitsParserFromFile.js +92 -89
- package/cjs/sync/offline/splitsParser/splitsParserFromSettings.js +45 -42
- package/cjs/sync/offline/syncTasks/fromObjectSyncTask.js +14 -4
- package/cjs/sync/polling/updaters/mySegmentsUpdater.js +30 -10
- package/cjs/sync/streaming/SSEClient/index.js +0 -11
- package/cjs/sync/streaming/SSEHandler/NotificationKeeper.js +7 -0
- package/cjs/sync/streaming/SSEHandler/NotificationParser.js +4 -1
- package/cjs/sync/streaming/SSEHandler/index.js +8 -9
- package/cjs/sync/streaming/SSEHandler/types.js +14 -0
- package/cjs/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +5 -5
- package/cjs/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.js +2 -1
- package/cjs/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +5 -3
- package/cjs/sync/streaming/constants.js +3 -1
- package/cjs/sync/streaming/mySegmentsV2utils.js +75 -0
- package/cjs/sync/streaming/pushManager.js +141 -40
- package/cjs/sync/submitters/metricsSyncTask.js +1 -1
- package/cjs/sync/submitters/submitterSyncTask.js +2 -2
- package/cjs/sync/syncManagerFromFile.js +15 -0
- package/cjs/sync/syncManagerFromObject.js +14 -0
- package/cjs/sync/syncManagerOffline.js +3 -3
- package/cjs/sync/syncManagerOnline.js +5 -3
- package/cjs/trackers/impressionObserver/ImpressionObserver.js +0 -2
- package/cjs/trackers/impressionObserver/buildKey.js +3 -9
- package/cjs/trackers/impressionObserver/impressionObserverCS.js +2 -2
- package/cjs/trackers/impressionObserver/impressionObserverSS.js +3 -3
- package/cjs/utils/constants/index.js +4 -1
- package/cjs/utils/decompress/index.js +427 -0
- package/cjs/utils/murmur3/{commons.js → common.js} +2 -6
- package/cjs/utils/murmur3/murmur3.js +11 -12
- package/cjs/utils/murmur3/murmur3_128.js +7 -142
- package/cjs/utils/murmur3/murmur3_128_x86.js +154 -0
- package/cjs/utils/murmur3/murmur3_64.js +36 -0
- package/cjs/utils/murmur3/utfx.js +100 -106
- package/cjs/utils/promise/wrapper.js +14 -11
- package/cjs/utils/settingsValidation/index.js +5 -2
- package/cjs/utils/settingsValidation/localhost/index.js +20 -0
- package/cjs/utils/settingsValidation/splitFilters.js +0 -1
- package/cjs/utils/settingsValidation/storage/storageCS.js +18 -8
- package/cjs/utils/settingsValidation/url.js +1 -1
- package/esm/evaluator/matchers/matcherTypes.js +2 -2
- package/esm/evaluator/matchersTransform/index.js +12 -12
- package/esm/evaluator/value/sanitize.js +7 -7
- package/esm/listeners/browser.js +1 -2
- package/esm/listeners/node.js +0 -3
- package/esm/logger/constants.js +2 -0
- package/esm/logger/messages/error.js +3 -2
- package/esm/logger/messages/info.js +2 -2
- package/esm/logger/messages/warn.js +2 -1
- package/esm/readiness/readinessManager.js +10 -7
- package/esm/sdkFactory/index.js +1 -4
- package/esm/services/splitApi.js +1 -1
- package/esm/services/splitHttpClient.js +5 -4
- package/esm/storages/AbstractSplitsCacheSync.js +1 -1
- package/esm/storages/inLocalStorage/index.js +5 -2
- package/esm/storages/inMemory/InMemoryStorage.js +2 -0
- package/esm/storages/inMemory/InMemoryStorageCS.js +2 -0
- package/esm/storages/inRedis/SplitsCacheInRedis.js +6 -2
- package/esm/storages/inRedis/index.js +5 -2
- package/esm/storages/pluggable/SplitsCachePluggable.js +6 -2
- package/esm/storages/pluggable/inMemoryWrapper.js +6 -7
- package/esm/storages/pluggable/index.js +5 -2
- package/esm/storages/pluggable/wrapperAdapter.js +0 -1
- package/esm/sync/offline/splitsParser/splitsParserFromFile.js +90 -88
- package/esm/sync/offline/splitsParser/splitsParserFromSettings.js +43 -41
- package/esm/sync/offline/syncTasks/fromObjectSyncTask.js +15 -5
- package/esm/sync/polling/updaters/mySegmentsUpdater.js +30 -10
- package/esm/sync/streaming/SSEClient/index.js +0 -11
- package/esm/sync/streaming/SSEHandler/NotificationKeeper.js +7 -0
- package/esm/sync/streaming/SSEHandler/NotificationParser.js +4 -1
- package/esm/sync/streaming/SSEHandler/index.js +9 -10
- package/esm/sync/streaming/SSEHandler/types.js +13 -1
- package/esm/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +5 -5
- package/esm/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.js +2 -1
- package/esm/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +5 -3
- package/esm/sync/streaming/constants.js +2 -0
- package/esm/sync/streaming/mySegmentsV2utils.js +69 -0
- package/esm/sync/streaming/pushManager.js +143 -42
- package/esm/sync/submitters/metricsSyncTask.js +1 -1
- package/esm/sync/submitters/submitterSyncTask.js +2 -2
- package/esm/sync/syncManagerFromFile.js +11 -0
- package/esm/sync/syncManagerFromObject.js +10 -0
- package/esm/sync/syncManagerOffline.js +3 -3
- package/esm/sync/syncManagerOnline.js +5 -3
- package/esm/trackers/impressionObserver/ImpressionObserver.js +0 -2
- package/esm/trackers/impressionObserver/buildKey.js +2 -9
- package/esm/trackers/impressionObserver/impressionObserverCS.js +2 -2
- package/esm/trackers/impressionObserver/impressionObserverSS.js +3 -3
- package/esm/utils/constants/index.js +3 -0
- package/esm/utils/decompress/index.js +424 -0
- package/esm/utils/murmur3/{commons.js → common.js} +1 -4
- package/esm/utils/murmur3/murmur3.js +1 -2
- package/esm/utils/murmur3/murmur3_128.js +7 -142
- package/esm/utils/murmur3/murmur3_128_x86.js +150 -0
- package/esm/utils/murmur3/murmur3_64.js +32 -0
- package/esm/utils/murmur3/utfx.js +96 -106
- package/esm/utils/promise/wrapper.js +14 -11
- package/esm/utils/settingsValidation/index.js +5 -2
- package/esm/utils/settingsValidation/localhost/index.js +16 -0
- package/esm/utils/settingsValidation/splitFilters.js +0 -1
- package/esm/utils/settingsValidation/storage/storageCS.js +16 -7
- package/esm/utils/settingsValidation/url.js +1 -1
- package/package.json +5 -5
- package/src/evaluator/matchers/matcherTypes.ts +2 -2
- package/src/evaluator/matchersTransform/index.ts +12 -12
- package/src/evaluator/value/sanitize.ts +7 -7
- package/src/listeners/browser.ts +1 -1
- package/src/listeners/node.ts +1 -2
- package/src/logger/constants.ts +2 -0
- package/src/logger/messages/error.ts +3 -2
- package/src/logger/messages/info.ts +2 -2
- package/src/logger/messages/warn.ts +3 -1
- package/src/readiness/readinessManager.ts +9 -7
- package/src/sdkFactory/index.ts +1 -3
- package/src/sdkFactory/types.ts +3 -3
- package/src/services/splitApi.ts +2 -3
- package/src/services/splitHttpClient.ts +6 -5
- package/src/services/types.ts +5 -5
- package/src/storages/AbstractSplitsCacheSync.ts +1 -1
- package/src/storages/inLocalStorage/index.ts +8 -4
- package/src/storages/inMemory/InMemoryStorage.ts +3 -0
- package/src/storages/inMemory/InMemoryStorageCS.ts +3 -0
- package/src/storages/inRedis/SplitsCacheInRedis.ts +3 -1
- package/src/storages/inRedis/index.ts +8 -4
- package/src/storages/pluggable/SplitsCachePluggable.ts +3 -1
- package/src/storages/pluggable/inMemoryWrapper.ts +6 -7
- package/src/storages/pluggable/index.ts +8 -4
- package/src/storages/pluggable/wrapperAdapter.ts +0 -1
- package/src/storages/types.ts +18 -15
- package/src/sync/offline/splitsParser/splitsParserFromFile.ts +110 -105
- package/src/sync/offline/splitsParser/splitsParserFromSettings.ts +45 -41
- package/src/sync/offline/syncTasks/fromObjectSyncTask.ts +15 -5
- package/src/sync/polling/types.ts +2 -1
- package/src/sync/polling/updaters/mySegmentsUpdater.ts +28 -10
- package/src/sync/streaming/AuthClient/types.ts +3 -0
- package/src/sync/streaming/SSEClient/index.ts +1 -15
- package/src/sync/streaming/SSEClient/types.ts +0 -1
- package/src/sync/streaming/SSEHandler/NotificationKeeper.ts +8 -0
- package/src/sync/streaming/SSEHandler/NotificationParser.ts +4 -2
- package/src/sync/streaming/SSEHandler/index.ts +11 -20
- package/src/sync/streaming/SSEHandler/types.ts +37 -3
- package/src/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.ts +7 -6
- package/src/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.ts +2 -1
- package/src/sync/streaming/UpdateWorkers/SplitsUpdateWorker.ts +4 -3
- package/src/sync/streaming/UpdateWorkers/types.ts +1 -1
- package/src/sync/streaming/constants.ts +2 -0
- package/src/sync/streaming/mySegmentsV2utils.ts +77 -0
- package/src/sync/streaming/pushManager.ts +139 -42
- package/src/sync/streaming/types.ts +14 -22
- package/src/sync/submitters/metricsSyncTask.ts +1 -1
- package/src/sync/submitters/submitterSyncTask.ts +2 -1
- package/src/sync/syncManagerFromFile.ts +13 -0
- package/src/sync/syncManagerFromObject.ts +12 -0
- package/src/sync/syncManagerOffline.ts +3 -3
- package/src/sync/syncManagerOnline.ts +6 -3
- package/src/trackers/impressionObserver/ImpressionObserver.ts +4 -6
- package/src/trackers/impressionObserver/buildKey.ts +2 -16
- package/src/trackers/impressionObserver/impressionObserverCS.ts +2 -2
- package/src/trackers/impressionObserver/impressionObserverSS.ts +3 -3
- package/src/types.ts +16 -2
- package/src/utils/constants/index.ts +6 -1
- package/src/utils/decompress/index.ts +429 -0
- package/src/utils/murmur3/{commons.ts → common.ts} +1 -5
- package/src/utils/murmur3/murmur3.ts +5 -5
- package/src/utils/murmur3/murmur3_128.ts +7 -180
- package/src/utils/murmur3/murmur3_128_x86.ts +188 -0
- package/src/utils/murmur3/murmur3_64.ts +36 -0
- package/src/utils/murmur3/utfx.ts +92 -110
- package/src/utils/promise/wrapper.ts +12 -9
- package/src/utils/settingsValidation/index.ts +8 -4
- package/src/utils/settingsValidation/localhost/index.ts +19 -0
- package/src/utils/settingsValidation/splitFilters.ts +0 -1
- package/src/utils/settingsValidation/storage/storageCS.ts +21 -8
- package/src/utils/settingsValidation/types.ts +2 -11
- package/src/utils/settingsValidation/url.ts +1 -1
- package/types/evaluator/matchers/matcherTypes.d.ts +2 -2
- package/types/listeners/browser.d.ts +1 -0
- package/types/listeners/node.d.ts +0 -1
- package/types/logger/constants.d.ts +2 -0
- package/types/sdkFactory/types.d.ts +3 -3
- package/types/services/types.d.ts +1 -0
- package/types/storages/inLocalStorage/index.d.ts +2 -2
- package/types/storages/inMemory/InMemoryStorage.d.ts +3 -0
- package/types/storages/inMemory/InMemoryStorageCS.d.ts +3 -0
- package/types/storages/inRedis/index.d.ts +2 -2
- package/types/storages/pluggable/index.d.ts +2 -2
- package/types/storages/types.d.ts +15 -15
- package/types/sync/offline/splitsParser/splitsParserFromFile.d.ts +2 -7
- package/types/sync/offline/splitsParser/splitsParserFromSettings.d.ts +1 -5
- package/types/sync/polling/types.d.ts +2 -1
- package/types/sync/streaming/AuthClient/indexV1.d.ts +12 -0
- package/types/sync/streaming/AuthClient/indexV2.d.ts +8 -0
- package/types/sync/streaming/AuthClient/types.d.ts +2 -0
- package/types/sync/streaming/SSEClient/index.d.ts +1 -9
- package/types/sync/streaming/SSEClient/types.d.ts +0 -1
- package/types/sync/streaming/SSEHandler/NotificationParser.d.ts +3 -2
- package/types/sync/streaming/SSEHandler/types.d.ts +30 -2
- package/types/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.d.ts +4 -3
- package/types/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.d.ts +2 -1
- package/types/sync/streaming/UpdateWorkers/SplitsUpdateWorker.d.ts +3 -2
- package/types/sync/streaming/UpdateWorkers/types.d.ts +1 -1
- package/types/sync/streaming/constants.d.ts +3 -1
- package/types/sync/streaming/mySegmentsV2utils.d.ts +27 -0
- package/types/sync/streaming/pushManagerNoUsers.d.ts +13 -0
- package/types/sync/streaming/types.d.ts +9 -5
- package/types/sync/submitters/submitterSyncTask.d.ts +1 -1
- package/types/sync/syncManagerFromFile.d.ts +2 -0
- package/types/sync/syncManagerFromObject.d.ts +2 -0
- package/types/sync/syncManagerOffline.d.ts +1 -1
- package/types/trackers/impressionObserver/ImpressionObserver.d.ts +2 -2
- package/types/trackers/impressionObserver/buildKey.d.ts +1 -1
- package/types/trackers/impressionObserver/impressionObserverCS.d.ts +2 -2
- package/types/trackers/impressionObserver/impressionObserverSS.d.ts +2 -2
- package/types/types.d.ts +16 -2
- package/types/utils/constants/index.d.ts +5 -1
- package/types/utils/decompress/index.d.ts +16 -0
- package/types/utils/murmur3/common.d.ts +12 -0
- package/types/utils/murmur3/murmur3.d.ts +2 -2
- package/types/utils/murmur3/murmur3_128.d.ts +5 -0
- package/types/utils/murmur3/murmur3_128_x86.d.ts +7 -0
- package/types/utils/murmur3/murmur3_64.d.ts +10 -0
- package/types/utils/murmur3/utfx.d.ts +24 -6
- package/types/utils/settingsValidation/index.d.ts +3 -2
- package/types/utils/settingsValidation/localhost/index.d.ts +9 -0
- package/types/utils/settingsValidation/storage/storageCS.d.ts +7 -1
- package/types/utils/settingsValidation/types.d.ts +2 -10
- package/cjs/sync/streaming/pushManagerCS.js +0 -179
- package/cjs/sync/streaming/pushManagerSS.js +0 -128
- package/esm/sync/streaming/pushManagerCS.js +0 -175
- package/esm/sync/streaming/pushManagerSS.js +0 -124
- package/src/sync/streaming/pushManagerCS.ts +0 -238
- package/src/sync/streaming/pushManagerSS.ts +0 -177
|
@@ -8,8 +8,12 @@ import { authenticateFactory, hashUserKey } from './AuthClient';
|
|
|
8
8
|
import { forOwn } from '../../utils/lang';
|
|
9
9
|
import SSEClient from './SSEClient';
|
|
10
10
|
import { getMatching } from '../../utils/key';
|
|
11
|
-
import { MY_SEGMENTS_UPDATE, PUSH_NONRETRYABLE_ERROR, PUSH_SUBSYSTEM_DOWN, SECONDS_BEFORE_EXPIRATION, SEGMENT_UPDATE, SPLIT_KILL, SPLIT_UPDATE, PUSH_RETRYABLE_ERROR, PUSH_SUBSYSTEM_UP } from './constants';
|
|
12
|
-
import { STREAMING_FALLBACK, STREAMING_REFRESH_TOKEN, STREAMING_CONNECTING, STREAMING_DISABLED, ERROR_STREAMING_AUTH, STREAMING_DISCONNECTING, STREAMING_RECONNECT } from '../../logger/constants';
|
|
11
|
+
import { MY_SEGMENTS_UPDATE, MY_SEGMENTS_UPDATE_V2, PUSH_NONRETRYABLE_ERROR, PUSH_SUBSYSTEM_DOWN, SECONDS_BEFORE_EXPIRATION, SEGMENT_UPDATE, SPLIT_KILL, SPLIT_UPDATE, PUSH_RETRYABLE_ERROR, PUSH_SUBSYSTEM_UP, ControlType } from './constants';
|
|
12
|
+
import { STREAMING_FALLBACK, STREAMING_REFRESH_TOKEN, STREAMING_CONNECTING, STREAMING_DISABLED, ERROR_STREAMING_AUTH, STREAMING_DISCONNECTING, STREAMING_RECONNECT, STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2 } from '../../logger/constants';
|
|
13
|
+
import { UpdateStrategy } from './SSEHandler/types';
|
|
14
|
+
import { isInBitmap, parseBitmap, parseKeyList } from './mySegmentsV2utils';
|
|
15
|
+
import { _Set } from '../../utils/lang/sets';
|
|
16
|
+
import { hash64 } from '../../utils/murmur3/murmur3_64';
|
|
13
17
|
/**
|
|
14
18
|
* PushManager factory:
|
|
15
19
|
* - for server-side if key is not provided in settings.
|
|
@@ -34,43 +38,58 @@ export default function pushManagerFactory(pollingManager, storage, readiness, f
|
|
|
34
38
|
var pushEmitter = new platform.EventEmitter();
|
|
35
39
|
var sseHandler = SSEHandlerFactory(log, pushEmitter);
|
|
36
40
|
sseClient.setEventHandler(sseHandler);
|
|
41
|
+
// init workers
|
|
42
|
+
var segmentsUpdateWorker = userKey ? new MySegmentsUpdateWorker(pollingManager.segmentsSyncTask) : new SegmentsUpdateWorker(storage.segments, pollingManager.segmentsSyncTask);
|
|
43
|
+
// For server-side we pass the segmentsSyncTask, used by SplitsUpdateWorker to fetch new segments
|
|
44
|
+
var splitsUpdateWorker = new SplitsUpdateWorker(storage.splits, pollingManager.splitsSyncTask, readiness.splits, userKey ? undefined : pollingManager.segmentsSyncTask);
|
|
37
45
|
// [Only for client-side] map of hashes to user keys, to dispatch MY_SEGMENTS_UPDATE events to the corresponding MySegmentsUpdateWorker
|
|
38
46
|
var userKeyHashes = {};
|
|
47
|
+
// [Only for client-side] map of user keys to their corresponding hash64 and MySegmentsUpdateWorkers.
|
|
48
|
+
// Hash64 is used to process MY_SEGMENTS_UPDATE_V2 events and dispatch actions to the corresponding MySegmentsUpdateWorker.
|
|
49
|
+
var clients = {};
|
|
39
50
|
if (userKey) {
|
|
40
51
|
var hash = hashUserKey(userKey);
|
|
41
52
|
userKeyHashes[hash] = userKey;
|
|
53
|
+
clients[userKey] = { hash64: hash64(userKey), worker: segmentsUpdateWorker };
|
|
42
54
|
}
|
|
43
|
-
// init workers
|
|
44
|
-
var segmentsUpdateWorker = userKey ? new MySegmentsUpdateWorker(pollingManager.segmentsSyncTask) : new SegmentsUpdateWorker(storage.segments, pollingManager.segmentsSyncTask);
|
|
45
|
-
// [Only for server-side] we pass the segmentsSyncTask, used by SplitsUpdateWorker to fetch new segments
|
|
46
|
-
var splitsUpdateWorker = new SplitsUpdateWorker(storage.splits, pollingManager.splitsSyncTask, readiness.splits, userKey ? undefined : pollingManager.segmentsSyncTask);
|
|
47
|
-
// [Only for client-side] map of user keys to their corresponding MySegmentsUpdateWorkers. It has a two-fold intention:
|
|
48
|
-
// - stop workers all together when push is disconnected
|
|
49
|
-
// - keep the current list of user keys to authenticate
|
|
50
|
-
var workers = {};
|
|
51
|
-
if (userKey)
|
|
52
|
-
workers[userKey] = segmentsUpdateWorker;
|
|
53
55
|
// [Only for client-side] variable to flag that a new client was added. It is needed to reconnect streaming.
|
|
54
56
|
var connectForNewClient = false;
|
|
55
|
-
// flag that indicates if `disconnectPush` was called, either by the SyncManager
|
|
57
|
+
// flag that indicates if `stop/disconnectPush` was called, either by the SyncManager, when the client is destroyed, or due to a PUSH_NONRETRYABLE_ERROR error.
|
|
56
58
|
// It is used to halt the `connectPush` process if it was in progress.
|
|
57
59
|
var disconnected;
|
|
60
|
+
// flag that indicates a PUSH_NONRETRYABLE_ERROR, condition with which starting pushManager again is ignored.
|
|
61
|
+
var disabled; // `disabled` implies `disconnected === true`
|
|
58
62
|
/** PushManager functions related to initialization */
|
|
59
63
|
var connectPushRetryBackoff = new Backoff(connectPush, settings.scheduler.pushRetryBackoffBase);
|
|
60
|
-
var
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
if
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
64
|
+
var timeoutIdTokenRefresh;
|
|
65
|
+
var timeoutIdSseOpen;
|
|
66
|
+
function scheduleTokenRefreshAndSse(authData) {
|
|
67
|
+
// clear scheduled tasks if exist
|
|
68
|
+
if (timeoutIdTokenRefresh)
|
|
69
|
+
clearTimeout(timeoutIdTokenRefresh);
|
|
70
|
+
if (timeoutIdSseOpen)
|
|
71
|
+
clearTimeout(timeoutIdSseOpen);
|
|
72
|
+
// Set token refresh 10 minutes before `expirationTime - issuedAt`
|
|
73
|
+
var decodedToken = authData.decodedToken;
|
|
74
|
+
var refreshTokenDelay = decodedToken.exp - decodedToken.iat - SECONDS_BEFORE_EXPIRATION;
|
|
75
|
+
// Default connDelay of 60 secs
|
|
76
|
+
var connDelay = typeof authData.connDelay === 'number' && authData.connDelay >= 0 ? authData.connDelay : 60;
|
|
77
|
+
log.info(STREAMING_REFRESH_TOKEN, [refreshTokenDelay, connDelay]);
|
|
78
|
+
timeoutIdTokenRefresh = setTimeout(connectPush, refreshTokenDelay * 1000);
|
|
79
|
+
timeoutIdSseOpen = setTimeout(function () {
|
|
80
|
+
// halt if disconnected
|
|
81
|
+
if (disconnected)
|
|
82
|
+
return;
|
|
83
|
+
sseClient.open(authData);
|
|
84
|
+
}, connDelay * 1000);
|
|
69
85
|
}
|
|
70
86
|
function connectPush() {
|
|
87
|
+
// Guard condition in case `stop/disconnectPush` has been called (e.g., calling SDK destroy, or app signal close/background)
|
|
88
|
+
if (disconnected)
|
|
89
|
+
return;
|
|
90
|
+
log.info(STREAMING_CONNECTING, [disconnected === undefined ? '' : 'Re-']);
|
|
71
91
|
disconnected = false;
|
|
72
|
-
|
|
73
|
-
var userKeys = userKey ? Object.keys(workers) : undefined;
|
|
92
|
+
var userKeys = userKey ? Object.keys(clients) : undefined;
|
|
74
93
|
authenticate(userKeys).then(function (authData) {
|
|
75
94
|
if (disconnected)
|
|
76
95
|
return;
|
|
@@ -82,12 +101,10 @@ export default function pushManagerFactory(pollingManager, storage, readiness, f
|
|
|
82
101
|
return;
|
|
83
102
|
}
|
|
84
103
|
// [Only for client-side] don't open SSE connection if a new shared client was added, since it means that a new authentication is taking place
|
|
85
|
-
if (userKeys && userKeys.length < Object.keys(
|
|
104
|
+
if (userKeys && userKeys.length < Object.keys(clients).length)
|
|
86
105
|
return;
|
|
87
|
-
//
|
|
88
|
-
|
|
89
|
-
sseClient.open(authData);
|
|
90
|
-
scheduleTokenRefresh(decodedToken.iat, decodedToken.exp);
|
|
106
|
+
// Schedule SSE connection and refresh token
|
|
107
|
+
scheduleTokenRefreshAndSse(authData);
|
|
91
108
|
}).catch(function (error) {
|
|
92
109
|
if (disconnected)
|
|
93
110
|
return;
|
|
@@ -103,11 +120,16 @@ export default function pushManagerFactory(pollingManager, storage, readiness, f
|
|
|
103
120
|
}
|
|
104
121
|
// close SSE connection and cancel scheduled tasks
|
|
105
122
|
function disconnectPush() {
|
|
106
|
-
|
|
123
|
+
// Halt disconnecting, just to avoid redundant logs if called multiple times
|
|
124
|
+
if (disconnected)
|
|
125
|
+
return;
|
|
107
126
|
disconnected = true;
|
|
127
|
+
sseClient.close();
|
|
108
128
|
log.info(STREAMING_DISCONNECTING);
|
|
109
|
-
if (
|
|
110
|
-
clearTimeout(
|
|
129
|
+
if (timeoutIdTokenRefresh)
|
|
130
|
+
clearTimeout(timeoutIdTokenRefresh);
|
|
131
|
+
if (timeoutIdSseOpen)
|
|
132
|
+
clearTimeout(timeoutIdSseOpen);
|
|
111
133
|
connectPushRetryBackoff.reset();
|
|
112
134
|
stopWorkers();
|
|
113
135
|
}
|
|
@@ -115,15 +137,23 @@ export default function pushManagerFactory(pollingManager, storage, readiness, f
|
|
|
115
137
|
function stopWorkers() {
|
|
116
138
|
splitsUpdateWorker.backoff.reset();
|
|
117
139
|
if (userKey)
|
|
118
|
-
forOwn(
|
|
140
|
+
forOwn(clients, function (_a) {
|
|
141
|
+
var worker = _a.worker;
|
|
142
|
+
return worker.backoff.reset();
|
|
143
|
+
});
|
|
119
144
|
else
|
|
120
145
|
segmentsUpdateWorker.backoff.reset();
|
|
121
146
|
}
|
|
122
147
|
pushEmitter.on(PUSH_SUBSYSTEM_DOWN, stopWorkers);
|
|
123
|
-
//
|
|
124
|
-
|
|
148
|
+
// Only required when streaming connects after a PUSH_RETRYABLE_ERROR.
|
|
149
|
+
// Otherwise it is unnecessary (e.g, STREAMING_RESUMED).
|
|
150
|
+
pushEmitter.on(PUSH_SUBSYSTEM_UP, function () {
|
|
151
|
+
connectPushRetryBackoff.reset();
|
|
152
|
+
stopWorkers();
|
|
153
|
+
});
|
|
125
154
|
/** Fallbacking without retry due to: STREAMING_DISABLED control event, or 'pushEnabled: false', or non-recoverable SSE and Authentication errors */
|
|
126
155
|
pushEmitter.on(PUSH_NONRETRYABLE_ERROR, function handleNonRetryableError() {
|
|
156
|
+
disabled = true;
|
|
127
157
|
// Note: `stopWorkers` is been called twice, but it is not harmful
|
|
128
158
|
disconnectPush();
|
|
129
159
|
pushEmitter.emit(PUSH_SUBSYSTEM_DOWN); // no harm if polling already
|
|
@@ -137,6 +167,16 @@ export default function pushManagerFactory(pollingManager, storage, readiness, f
|
|
|
137
167
|
log.info(STREAMING_RECONNECT, [delayInMillis / 1000]);
|
|
138
168
|
pushEmitter.emit(PUSH_SUBSYSTEM_DOWN); // no harm if polling already
|
|
139
169
|
});
|
|
170
|
+
/** STREAMING_RESET notification. Unlike a PUSH_RETRYABLE_ERROR, it doesn't emit PUSH_SUBSYSTEM_DOWN to fallback polling */
|
|
171
|
+
pushEmitter.on(ControlType.STREAMING_RESET, function handleStreamingReset() {
|
|
172
|
+
if (disconnected)
|
|
173
|
+
return; // should never happen
|
|
174
|
+
// Minimum required clean-up.
|
|
175
|
+
// `disconnectPush` cannot be called because it sets `disconnected` and thus `connectPush` will not execute
|
|
176
|
+
if (timeoutIdTokenRefresh)
|
|
177
|
+
clearTimeout(timeoutIdTokenRefresh);
|
|
178
|
+
connectPush();
|
|
179
|
+
});
|
|
140
180
|
/** Functions related to synchronization (Queues and Workers in the spec) */
|
|
141
181
|
pushEmitter.on(SPLIT_KILL, splitsUpdateWorker.killSplit);
|
|
142
182
|
pushEmitter.on(SPLIT_UPDATE, splitsUpdateWorker.put);
|
|
@@ -144,10 +184,71 @@ export default function pushManagerFactory(pollingManager, storage, readiness, f
|
|
|
144
184
|
pushEmitter.on(MY_SEGMENTS_UPDATE, function handleMySegmentsUpdate(parsedData, channel) {
|
|
145
185
|
var userKeyHash = channel.split('_')[2];
|
|
146
186
|
var userKey = userKeyHashes[userKeyHash];
|
|
147
|
-
if (userKey &&
|
|
148
|
-
|
|
149
|
-
|
|
187
|
+
if (userKey && clients[userKey]) { // check existence since it can be undefined if client has been destroyed
|
|
188
|
+
clients[userKey].worker.put(parsedData.changeNumber, parsedData.includesPayload ? parsedData.segmentList ? parsedData.segmentList : [] : undefined);
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
pushEmitter.on(MY_SEGMENTS_UPDATE_V2, function handleMySegmentsUpdate(parsedData) {
|
|
192
|
+
switch (parsedData.u) {
|
|
193
|
+
case UpdateStrategy.BoundedFetchRequest: {
|
|
194
|
+
var bitmap_1;
|
|
195
|
+
try {
|
|
196
|
+
bitmap_1 = parseBitmap(parsedData.d, parsedData.c);
|
|
197
|
+
}
|
|
198
|
+
catch (e) {
|
|
199
|
+
log.warn(STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2, ['BoundedFetchRequest', e]);
|
|
200
|
+
break;
|
|
201
|
+
}
|
|
202
|
+
forOwn(clients, function (_a) {
|
|
203
|
+
var hash64 = _a.hash64, worker = _a.worker;
|
|
204
|
+
if (isInBitmap(bitmap_1, hash64.hex)) {
|
|
205
|
+
worker.put(parsedData.changeNumber); // fetch mySegments
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
case UpdateStrategy.KeyList: {
|
|
211
|
+
var keyList = void 0, added_1, removed_1;
|
|
212
|
+
try {
|
|
213
|
+
keyList = parseKeyList(parsedData.d, parsedData.c);
|
|
214
|
+
added_1 = new _Set(keyList.a);
|
|
215
|
+
removed_1 = new _Set(keyList.r);
|
|
216
|
+
}
|
|
217
|
+
catch (e) {
|
|
218
|
+
log.warn(STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2, ['KeyList', e]);
|
|
219
|
+
break;
|
|
220
|
+
}
|
|
221
|
+
forOwn(clients, function (_a) {
|
|
222
|
+
var hash64 = _a.hash64, worker = _a.worker;
|
|
223
|
+
var add = added_1.has(hash64.dec) ? true : removed_1.has(hash64.dec) ? false : undefined;
|
|
224
|
+
if (add !== undefined) {
|
|
225
|
+
worker.put(parsedData.changeNumber, {
|
|
226
|
+
name: parsedData.segmentName,
|
|
227
|
+
add: add
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
case UpdateStrategy.SegmentRemoval:
|
|
234
|
+
if (!parsedData.segmentName) {
|
|
235
|
+
log.warn(STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2, ['SegmentRemoval', 'No segment name was provided']);
|
|
236
|
+
break;
|
|
237
|
+
}
|
|
238
|
+
forOwn(clients, function (_a) {
|
|
239
|
+
var worker = _a.worker;
|
|
240
|
+
return worker.put(parsedData.changeNumber, {
|
|
241
|
+
name: parsedData.segmentName,
|
|
242
|
+
add: false
|
|
243
|
+
});
|
|
244
|
+
});
|
|
245
|
+
return;
|
|
150
246
|
}
|
|
247
|
+
// `UpdateStrategy.UnboundedFetchRequest` and fallbacks of other cases
|
|
248
|
+
forOwn(clients, function (_a) {
|
|
249
|
+
var worker = _a.worker;
|
|
250
|
+
worker.put(parsedData.changeNumber);
|
|
251
|
+
});
|
|
151
252
|
});
|
|
152
253
|
}
|
|
153
254
|
else {
|
|
@@ -159,8 +260,8 @@ export default function pushManagerFactory(pollingManager, storage, readiness, f
|
|
|
159
260
|
// Expose functionality for starting and stoping push mode:
|
|
160
261
|
stop: disconnectPush,
|
|
161
262
|
start: function () {
|
|
162
|
-
// Guard condition to avoid calling `connectPush` again if the `start` method is called multiple times.
|
|
163
|
-
if (disconnected === false)
|
|
263
|
+
// Guard condition to avoid calling `connectPush` again if the `start` method is called multiple times or if push has been disabled.
|
|
264
|
+
if (disabled || disconnected === false)
|
|
164
265
|
return;
|
|
165
266
|
disconnected = false;
|
|
166
267
|
// Run in next event-loop cycle for optimization on client-side: if multiple clients are created in the same cycle than the factory, only one authentication is performed.
|
|
@@ -168,8 +269,7 @@ export default function pushManagerFactory(pollingManager, storage, readiness, f
|
|
|
168
269
|
},
|
|
169
270
|
// [Only for client-side]
|
|
170
271
|
add: function (userKey, mySegmentsSyncTask) {
|
|
171
|
-
|
|
172
|
-
workers[userKey] = mySegmentsUpdateWorker;
|
|
272
|
+
clients[userKey] = { hash64: hash64(userKey), worker: new MySegmentsUpdateWorker(mySegmentsSyncTask) };
|
|
173
273
|
var hash = hashUserKey(userKey);
|
|
174
274
|
if (!userKeyHashes[hash]) {
|
|
175
275
|
userKeyHashes[hash] = userKey;
|
|
@@ -189,6 +289,7 @@ export default function pushManagerFactory(pollingManager, storage, readiness, f
|
|
|
189
289
|
remove: function (userKey) {
|
|
190
290
|
var hash = hashUserKey(userKey);
|
|
191
291
|
delete userKeyHashes[hash];
|
|
292
|
+
delete clients[userKey];
|
|
192
293
|
}
|
|
193
294
|
});
|
|
194
295
|
}
|
|
@@ -22,5 +22,5 @@ export function countsSyncTaskFactory(log, postMetricsCounters, countsCache, met
|
|
|
22
22
|
*/
|
|
23
23
|
export function latenciesSyncTaskFactory(log, postMetricsLatencies, latenciesCache, metricsRefreshRate, latencyTracker) {
|
|
24
24
|
// don't retry metrics.
|
|
25
|
-
return submitterSyncTaskFactory(log, postMetricsLatencies, latenciesCache, metricsRefreshRate, 'latency metrics', latencyTracker, fromCache('latencies'));
|
|
25
|
+
return submitterSyncTaskFactory(log, postMetricsLatencies, latenciesCache, metricsRefreshRate, 'latency metrics', latencyTracker, fromCache('latencies'), 0, true);
|
|
26
26
|
}
|
|
@@ -3,7 +3,7 @@ import { SUBMITTERS_PUSH, SUBMITTERS_PUSH_FAILS, SUBMITTERS_PUSH_RETRY } from '.
|
|
|
3
3
|
/**
|
|
4
4
|
* Base function to create submitter sync tasks, such as ImpressionsSyncTask and EventsSyncTask
|
|
5
5
|
*/
|
|
6
|
-
export function submitterSyncTaskFactory(log, postClient, sourceCache, postRate, dataName, latencyTracker, fromCacheToPayload, maxRetries) {
|
|
6
|
+
export function submitterSyncTaskFactory(log, postClient, sourceCache, postRate, dataName, latencyTracker, fromCacheToPayload, maxRetries, debugLogs) {
|
|
7
7
|
if (maxRetries === void 0) { maxRetries = 0; }
|
|
8
8
|
var retries = 0;
|
|
9
9
|
function postData() {
|
|
@@ -11,7 +11,7 @@ export function submitterSyncTaskFactory(log, postClient, sourceCache, postRate,
|
|
|
11
11
|
return Promise.resolve();
|
|
12
12
|
var data = sourceCache.state();
|
|
13
13
|
var dataCount = typeof data.length === 'number' ? data.length : '';
|
|
14
|
-
log
|
|
14
|
+
log[debugLogs ? 'debug' : 'info'](SUBMITTERS_PUSH, [dataCount, dataName]);
|
|
15
15
|
var latencyTrackerStop = latencyTracker && latencyTracker.start();
|
|
16
16
|
var jsonPayload = JSON.stringify(fromCacheToPayload ? fromCacheToPayload(data) : data);
|
|
17
17
|
if (!maxRetries)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { splitsParserFromFileFactory } from './offline/splitsParser/splitsParserFromFile';
|
|
2
|
+
import { syncManagerOfflineFactory } from './syncManagerOffline';
|
|
3
|
+
import { LOCALHOST_MODE } from '../utils/constants';
|
|
4
|
+
// Factory of Localhost SyncManager based on yaml file.
|
|
5
|
+
// Requires Node 'fs' and 'path' APIs.
|
|
6
|
+
export function LocalhostFromFile() {
|
|
7
|
+
var localhost = syncManagerOfflineFactory(splitsParserFromFileFactory);
|
|
8
|
+
// @ts-ignore
|
|
9
|
+
localhost.type = LOCALHOST_MODE;
|
|
10
|
+
return localhost;
|
|
11
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { splitsParserFromSettingsFactory } from './offline/splitsParser/splitsParserFromSettings';
|
|
2
|
+
import { syncManagerOfflineFactory } from './syncManagerOffline';
|
|
3
|
+
import { LOCALHOST_MODE } from '../utils/constants';
|
|
4
|
+
// Factory of Localhost SyncManager based on JS object.
|
|
5
|
+
export function LocalhostFromObject() {
|
|
6
|
+
var localhost = syncManagerOfflineFactory(splitsParserFromSettingsFactory);
|
|
7
|
+
// @ts-ignore
|
|
8
|
+
localhost.type = LOCALHOST_MODE;
|
|
9
|
+
return localhost;
|
|
10
|
+
}
|
|
@@ -10,20 +10,20 @@ function flush() {
|
|
|
10
10
|
*
|
|
11
11
|
* @param splitsParser e.g., `splitsParserFromFile`, `splitsParserFromSettings`.
|
|
12
12
|
*/
|
|
13
|
-
export function syncManagerOfflineFactory(
|
|
13
|
+
export function syncManagerOfflineFactory(splitsParserFactory) {
|
|
14
14
|
/**
|
|
15
15
|
* SyncManager factory for modular SDK
|
|
16
16
|
*/
|
|
17
17
|
return function (_a) {
|
|
18
18
|
var settings = _a.settings, readiness = _a.readiness, storage = _a.storage;
|
|
19
|
-
return objectAssign(fromObjectSyncTaskFactory(
|
|
19
|
+
return objectAssign(fromObjectSyncTaskFactory(splitsParserFactory(), storage, readiness, settings), {
|
|
20
20
|
// fake flush, that resolves immediately
|
|
21
21
|
flush: flush,
|
|
22
22
|
// [Only used for client-side]
|
|
23
23
|
shared: function (matchingKey, readinessManager) {
|
|
24
24
|
return {
|
|
25
25
|
start: function () {
|
|
26
|
-
// In LOCALHOST mode, shared clients are ready in the next event cycle than created
|
|
26
|
+
// In LOCALHOST mode, shared clients are ready in the next event-loop cycle than created
|
|
27
27
|
// SDK_READY cannot be emitted directly because this will not update the readiness status
|
|
28
28
|
setTimeout(function () {
|
|
29
29
|
readinessManager.segments.emit(SDK_SEGMENTS_ARRIVED); // SDK_SPLITS_ARRIVED emitted by main SyncManager
|
|
@@ -53,6 +53,10 @@ export function syncManagerOnlineFactory(pollingManagerFactory, pushManagerFacto
|
|
|
53
53
|
// fetch splits and segments. There is no need to catch this promise (it is always resolved)
|
|
54
54
|
pollingManager.syncAll();
|
|
55
55
|
}
|
|
56
|
+
if (pushManager) {
|
|
57
|
+
pushManager.on(PUSH_SUBSYSTEM_UP, stopPollingAndSyncAll);
|
|
58
|
+
pushManager.on(PUSH_SUBSYSTEM_DOWN, startPolling);
|
|
59
|
+
}
|
|
56
60
|
var running = false; // flag that indicates whether the syncManager has been started (true) or stopped (false)
|
|
57
61
|
var startFirstTime = true; // flag to distinguish calling the `start` method for the first time, to support pausing and resuming the synchronization
|
|
58
62
|
return {
|
|
@@ -63,11 +67,9 @@ export function syncManagerOnlineFactory(pollingManagerFactory, pushManagerFacto
|
|
|
63
67
|
start: function () {
|
|
64
68
|
// start syncing splits and segments
|
|
65
69
|
if (pushManager) {
|
|
66
|
-
//
|
|
70
|
+
// Doesn't call `syncAll` when the syncManager is resuming
|
|
67
71
|
if (startFirstTime) {
|
|
68
72
|
pollingManager.syncAll();
|
|
69
|
-
pushManager.on(PUSH_SUBSYSTEM_UP, stopPollingAndSyncAll);
|
|
70
|
-
pushManager.on(PUSH_SUBSYSTEM_DOWN, startPolling);
|
|
71
73
|
startFirstTime = false;
|
|
72
74
|
}
|
|
73
75
|
pushManager.start();
|
|
@@ -5,8 +5,6 @@ var ImpressionObserver = /** @class */ (function () {
|
|
|
5
5
|
this.hasher = hasher;
|
|
6
6
|
}
|
|
7
7
|
ImpressionObserver.prototype.testAndSet = function (impression) {
|
|
8
|
-
if (!impression)
|
|
9
|
-
return;
|
|
10
8
|
var hash = this.hasher(impression);
|
|
11
9
|
var previous = this.cache.get(hash);
|
|
12
10
|
this.cache.set(hash, impression.time);
|
|
@@ -1,10 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
return s ? s : UNKNOWN;
|
|
4
|
-
}
|
|
5
|
-
function _zeroIfNull(l) {
|
|
6
|
-
return l ? l : 0;
|
|
7
|
-
}
|
|
8
|
-
export default function buildKey(impression) {
|
|
9
|
-
return _unknownIfNull(impression.keyName) + "\n :" + _unknownIfNull(impression.feature) + "\n :" + _unknownIfNull(impression.treatment) + "\n :" + _unknownIfNull(impression.label) + "\n :" + _zeroIfNull(impression.changeNumber);
|
|
1
|
+
export function buildKey(impression) {
|
|
2
|
+
return impression.keyName + ":" + impression.feature + ":" + impression.treatment + ":" + impression.label + ":" + impression.changeNumber;
|
|
10
3
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import ImpressionObserver from './ImpressionObserver';
|
|
2
2
|
import { hash } from '../../utils/murmur3/murmur3';
|
|
3
|
-
import buildKey from './buildKey';
|
|
3
|
+
import { buildKey } from './buildKey';
|
|
4
4
|
export function hashImpression32(impression) {
|
|
5
|
-
return
|
|
5
|
+
return hash(buildKey(impression));
|
|
6
6
|
}
|
|
7
7
|
var LAST_SEEN_CACHE_SIZE = 500; // cache up to 500 impression hashes
|
|
8
8
|
export function impressionObserverCSFactory() {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import ImpressionObserver from './ImpressionObserver';
|
|
2
|
-
import { hash128 } from '../../utils/murmur3/
|
|
3
|
-
import buildKey from './buildKey';
|
|
2
|
+
import { hash128 } from '../../utils/murmur3/murmur3_128_x86';
|
|
3
|
+
import { buildKey } from './buildKey';
|
|
4
4
|
export function hashImpression128(impression) {
|
|
5
|
-
return
|
|
5
|
+
return hash128(buildKey(impression));
|
|
6
6
|
}
|
|
7
7
|
var LAST_SEEN_CACHE_SIZE = 500000; // cache up to 500k impression hashes
|
|
8
8
|
export function impressionObserverSSFactory() {
|
|
@@ -20,3 +20,6 @@ export var PRODUCER_MODE = 'producer';
|
|
|
20
20
|
export var CONSUMER_MODE = 'consumer';
|
|
21
21
|
// Storage types
|
|
22
22
|
export var STORAGE_MEMORY = 'MEMORY';
|
|
23
|
+
export var STORAGE_LOCALSTORAGE = 'LOCALSTORAGE';
|
|
24
|
+
export var STORAGE_REDIS = 'REDIS';
|
|
25
|
+
export var STORAGE_CUSTOM = 'CUSTOM';
|