@splitsoftware/splitio-commons 3.1.1-rc.1 → 3.1.1-rc.11
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/CHANGES.txt +12 -1
- package/cjs/evaluator/index.js +11 -6
- package/cjs/presets/serverSide.js +3 -3
- package/cjs/sdkClient/client.js +3 -5
- package/cjs/sdkClient/sdkLifecycle.js +2 -0
- package/cjs/services/authProvider.js +23 -10
- package/cjs/services/secureSplitHttpClient.js +10 -13
- package/cjs/services/serviceApi.js +23 -21
- package/cjs/services/splitApi.js +10 -9
- package/cjs/storages/inRedis/RedisAdapter.js +8 -5
- package/cjs/sync/polling/pollingManagerCS.js +84 -79
- package/cjs/sync/polling/pollingManagerSS.js +43 -35
- package/cjs/sync/polling/updaters/definitionChangesUpdater.js +2 -2
- package/cjs/sync/polling/updaters/segmentChangesUpdater.js +1 -1
- package/cjs/sync/streaming/AuthClient/index.js +13 -14
- package/cjs/sync/streaming/SSEHandler/index.js +1 -0
- package/cjs/sync/streaming/constants.js +2 -1
- package/cjs/sync/streaming/pushManager.js +5 -10
- package/cjs/sync/submitters/impressionsSubmitter.js +1 -1
- package/cjs/sync/syncManagerOnline.js +2 -7
- package/cjs/utils/Backoff.js +16 -4
- package/esm/evaluator/index.js +11 -6
- package/esm/presets/serverSide.js +3 -3
- package/esm/sdkClient/client.js +3 -5
- package/esm/sdkClient/sdkLifecycle.js +2 -0
- package/esm/services/authProvider.js +24 -11
- package/esm/services/secureSplitHttpClient.js +10 -13
- package/esm/services/serviceApi.js +24 -22
- package/esm/services/splitApi.js +10 -9
- package/esm/storages/inRedis/RedisAdapter.js +8 -5
- package/esm/sync/polling/pollingManagerCS.js +84 -79
- package/esm/sync/polling/pollingManagerSS.js +43 -35
- package/esm/sync/polling/updaters/definitionChangesUpdater.js +3 -3
- package/esm/sync/polling/updaters/segmentChangesUpdater.js +1 -1
- package/esm/sync/streaming/AuthClient/index.js +11 -11
- package/esm/sync/streaming/SSEHandler/index.js +2 -1
- package/esm/sync/streaming/constants.js +1 -0
- package/esm/sync/streaming/pushManager.js +6 -11
- package/esm/sync/submitters/impressionsSubmitter.js +1 -1
- package/esm/sync/syncManagerOnline.js +2 -7
- package/esm/utils/Backoff.js +16 -4
- package/package.json +6 -7
- package/src/dtos/types.ts +1 -1
- package/src/evaluator/index.ts +11 -5
- package/src/evaluator/types.ts +1 -0
- package/src/presets/serverSide.ts +3 -3
- package/src/sdkClient/client.ts +3 -4
- package/src/sdkClient/sdkLifecycle.ts +3 -0
- package/src/services/authProvider.ts +41 -19
- package/src/services/secureSplitHttpClient.ts +10 -18
- package/src/services/serviceApi.ts +27 -24
- package/src/services/splitApi.ts +10 -9
- package/src/services/types.ts +5 -4
- package/src/storages/inRedis/RedisAdapter.ts +8 -5
- package/src/sync/polling/pollingManagerCS.ts +80 -78
- package/src/sync/polling/pollingManagerSS.ts +49 -45
- package/src/sync/polling/updaters/definitionChangesUpdater.ts +3 -3
- package/src/sync/polling/updaters/segmentChangesUpdater.ts +1 -1
- package/src/sync/streaming/AuthClient/index.ts +14 -15
- package/src/sync/streaming/AuthClient/types.ts +9 -13
- package/src/sync/streaming/SSEClient/index.ts +2 -2
- package/src/sync/streaming/SSEClient/types.ts +2 -2
- package/src/sync/streaming/SSEHandler/index.ts +2 -1
- package/src/sync/streaming/SSEHandler/types.ts +2 -2
- package/src/sync/streaming/constants.ts +1 -0
- package/src/sync/streaming/pushManager.ts +32 -42
- package/src/sync/streaming/types.ts +3 -2
- package/src/sync/submitters/impressionsSubmitter.ts +3 -3
- package/src/sync/submitters/types.ts +2 -2
- package/src/sync/syncManagerOnline.ts +2 -8
- package/src/utils/Backoff.ts +16 -4
- package/types/splitio.d.ts +5 -4
|
@@ -1,26 +1,37 @@
|
|
|
1
1
|
import { splitHttpClientFactory } from './splitHttpClient';
|
|
2
2
|
import { objectAssign } from '../utils/lang/objectAssign';
|
|
3
|
-
import { SPLITS, IMPRESSIONS, IMPRESSIONS_COUNT, EVENTS, TELEMETRY,
|
|
3
|
+
import { SPLITS, IMPRESSIONS, IMPRESSIONS_COUNT, EVENTS, TELEMETRY, SEGMENT, MEMBERSHIPS } from '../utils/constants';
|
|
4
4
|
import { ERROR_TOO_MANY_SETS } from '../logger/constants';
|
|
5
|
+
import { authProviderFactory } from './authProvider';
|
|
6
|
+
import { secureSplitHttpClientFactory } from './secureSplitHttpClient';
|
|
5
7
|
var noCacheHeaderOptions = { headers: { 'Cache-Control': 'no-cache' } };
|
|
6
|
-
function userKeyToQueryParam(userKey) {
|
|
7
|
-
return 'users=' + encodeURIComponent(userKey); // no need to check availability of `encodeURIComponent`, since it is a global highly supported.
|
|
8
|
-
}
|
|
9
8
|
/**
|
|
10
9
|
* Factory of ServiceApi objects, which group the collection of HTTP endpoints used by the SDKs
|
|
11
10
|
*
|
|
12
11
|
* @param settings - validated settings object
|
|
13
12
|
* @param platform - object containing environment-specific dependencies
|
|
14
13
|
* @param telemetryTracker - telemetry tracker
|
|
15
|
-
* @param secureSplitHttpClientFactory - factory of SecureSplitHttpClient objects
|
|
16
14
|
*/
|
|
17
|
-
export function serviceApiFactory(settings, platform, telemetryTracker
|
|
15
|
+
export function serviceApiFactory(settings, platform, telemetryTracker) {
|
|
18
16
|
var urls = settings.urls;
|
|
19
17
|
var filterQueryString = settings.sync.__splitFiltersValidation && settings.sync.__splitFiltersValidation.queryString;
|
|
20
18
|
var SplitSDKImpressionsMode = settings.sync.impressionsMode;
|
|
21
19
|
var splitHttpClient = splitHttpClientFactory(settings, platform);
|
|
22
|
-
|
|
20
|
+
// Shared authProvider so that the SSE authentication (via `fetchAuth`,
|
|
21
|
+
// used by `pushManager`) and every authenticated HTTP request to the Configs
|
|
22
|
+
// API reuse the same cached credential instead of each fetching their own.
|
|
23
|
+
var authProvider = authProviderFactory(settings, splitHttpClient, telemetryTracker);
|
|
24
|
+
var secureSplitHttpClient = secureSplitHttpClientFactory(splitHttpClient, authProvider);
|
|
25
|
+
var initialAuth = true;
|
|
23
26
|
return {
|
|
27
|
+
fetchAuth: function () {
|
|
28
|
+
// Guard condition to avoid invalidating the cached credential on the first pushManager authentication
|
|
29
|
+
if (initialAuth)
|
|
30
|
+
initialAuth = false;
|
|
31
|
+
else
|
|
32
|
+
authProvider.invalidate();
|
|
33
|
+
return authProvider.credential();
|
|
34
|
+
},
|
|
24
35
|
// @TODO throw errors if health check requests fail, to log them in the Synchronizer
|
|
25
36
|
getSdkAPIHealthCheck: function () {
|
|
26
37
|
var url = "".concat(urls.sdk, "/api/version");
|
|
@@ -30,15 +41,6 @@ export function serviceApiFactory(settings, platform, telemetryTracker, secureSp
|
|
|
30
41
|
var url = "".concat(urls.events, "/api/version");
|
|
31
42
|
return splitHttpClient(url).then(function () { return true; }).catch(function () { return false; });
|
|
32
43
|
},
|
|
33
|
-
fetchAuth: function (userMatchingKeys) {
|
|
34
|
-
var url = "".concat(urls.auth, "/api/v2/auth?s=").concat(settings.sync.flagSpecVersion);
|
|
35
|
-
if (userMatchingKeys) { // `userMatchingKeys` is undefined in server-side
|
|
36
|
-
var queryParams = userMatchingKeys.map(userKeyToQueryParam).join('&');
|
|
37
|
-
if (queryParams)
|
|
38
|
-
url += '&' + queryParams;
|
|
39
|
-
}
|
|
40
|
-
return splitHttpClient(url, undefined, telemetryTracker.trackHttp(TOKEN));
|
|
41
|
-
},
|
|
42
44
|
fetchSplitChanges: function (since, noCache, till, rbSince) {
|
|
43
45
|
var url = "".concat(urls.sdk, "/api/splitChanges?s=").concat(settings.sync.flagSpecVersion, "&since=").concat(since).concat(rbSince ? '&rbSince=' + rbSince : '').concat(filterQueryString || '').concat(till ? '&till=' + till : '');
|
|
44
46
|
return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined, telemetryTracker.trackHttp(SPLITS))
|
|
@@ -79,7 +81,7 @@ export function serviceApiFactory(settings, platform, telemetryTracker, secureSp
|
|
|
79
81
|
*/
|
|
80
82
|
postEventsBulk: function (body, headers) {
|
|
81
83
|
var url = "".concat(urls.events, "/api/events/bulk");
|
|
82
|
-
return
|
|
84
|
+
return secureSplitHttpClient(url, { method: 'POST', body: body, headers: headers }, telemetryTracker.trackHttp(EVENTS), false, false, false);
|
|
83
85
|
},
|
|
84
86
|
/**
|
|
85
87
|
* Post impressions.
|
|
@@ -89,12 +91,12 @@ export function serviceApiFactory(settings, platform, telemetryTracker, secureSp
|
|
|
89
91
|
*/
|
|
90
92
|
postTestImpressionsBulk: function (body, headers) {
|
|
91
93
|
var url = "".concat(urls.events, "/api/testImpressions/bulk");
|
|
92
|
-
return
|
|
94
|
+
return secureSplitHttpClient(url, {
|
|
93
95
|
// Adding extra headers to send impressions in OPTIMIZED or DEBUG modes.
|
|
94
96
|
method: 'POST',
|
|
95
97
|
body: body,
|
|
96
98
|
headers: objectAssign({ SplitSDKImpressionsMode: SplitSDKImpressionsMode }, headers)
|
|
97
|
-
}, telemetryTracker.trackHttp(IMPRESSIONS));
|
|
99
|
+
}, telemetryTracker.trackHttp(IMPRESSIONS), false, false, false);
|
|
98
100
|
},
|
|
99
101
|
/**
|
|
100
102
|
* Post impressions counts.
|
|
@@ -104,7 +106,7 @@ export function serviceApiFactory(settings, platform, telemetryTracker, secureSp
|
|
|
104
106
|
*/
|
|
105
107
|
postTestImpressionsCount: function (body, headers) {
|
|
106
108
|
var url = "".concat(urls.events, "/api/testImpressions/count");
|
|
107
|
-
return
|
|
109
|
+
return secureSplitHttpClient(url, { method: 'POST', body: body, headers: headers }, telemetryTracker.trackHttp(IMPRESSIONS_COUNT), false, false, false);
|
|
108
110
|
},
|
|
109
111
|
/**
|
|
110
112
|
* Post unique keys for client side.
|
|
@@ -114,7 +116,7 @@ export function serviceApiFactory(settings, platform, telemetryTracker, secureSp
|
|
|
114
116
|
*/
|
|
115
117
|
postUniqueKeysBulkCs: function (body, headers) {
|
|
116
118
|
var url = "".concat(urls.telemetry, "/api/v1/keys/cs");
|
|
117
|
-
return
|
|
119
|
+
return secureSplitHttpClient(url, { method: 'POST', body: body, headers: headers }, telemetryTracker.trackHttp(TELEMETRY), false, false, false);
|
|
118
120
|
},
|
|
119
121
|
/**
|
|
120
122
|
* Post unique keys for server side.
|
|
@@ -124,7 +126,7 @@ export function serviceApiFactory(settings, platform, telemetryTracker, secureSp
|
|
|
124
126
|
*/
|
|
125
127
|
postUniqueKeysBulkSs: function (body, headers) {
|
|
126
128
|
var url = "".concat(urls.telemetry, "/api/v1/keys/ss");
|
|
127
|
-
return
|
|
129
|
+
return secureSplitHttpClient(url, { method: 'POST', body: body, headers: headers }, telemetryTracker.trackHttp(TELEMETRY), false, false, false);
|
|
128
130
|
},
|
|
129
131
|
postMetricsConfig: function (body, headers) {
|
|
130
132
|
var url = "".concat(urls.telemetry, "/api/v1/metrics/config");
|
package/esm/services/splitApi.js
CHANGED
|
@@ -2,6 +2,7 @@ import { splitHttpClientFactory } from './splitHttpClient';
|
|
|
2
2
|
import { objectAssign } from '../utils/lang/objectAssign';
|
|
3
3
|
import { SPLITS, IMPRESSIONS, IMPRESSIONS_COUNT, EVENTS, TELEMETRY, TOKEN, SEGMENT, MEMBERSHIPS } from '../utils/constants';
|
|
4
4
|
import { ERROR_TOO_MANY_SETS } from '../logger/constants';
|
|
5
|
+
import { fetchAuthFactory } from '../sync/streaming/AuthClient';
|
|
5
6
|
var noCacheHeaderOptions = { headers: { 'Cache-Control': 'no-cache' } };
|
|
6
7
|
function userKeyToQueryParam(userKey) {
|
|
7
8
|
return 'users=' + encodeURIComponent(userKey); // no need to check availability of `encodeURIComponent`, since it is a global highly supported.
|
|
@@ -20,6 +21,15 @@ export function splitApiFactory(settings, platform, telemetryTracker) {
|
|
|
20
21
|
var SplitSDKImpressionsMode = settings.sync.impressionsMode;
|
|
21
22
|
var splitHttpClient = splitHttpClientFactory(settings, platform);
|
|
22
23
|
return {
|
|
24
|
+
fetchAuth: fetchAuthFactory(function (userMatchingKeys) {
|
|
25
|
+
var url = "".concat(urls.auth, "/v2/auth?s=").concat(settings.sync.flagSpecVersion);
|
|
26
|
+
if (userMatchingKeys) { // `userMatchingKeys` is undefined in server-side
|
|
27
|
+
var queryParams = userMatchingKeys.map(userKeyToQueryParam).join('&');
|
|
28
|
+
if (queryParams)
|
|
29
|
+
url += '&' + queryParams;
|
|
30
|
+
}
|
|
31
|
+
return splitHttpClient(url, undefined, telemetryTracker.trackHttp(TOKEN));
|
|
32
|
+
}),
|
|
23
33
|
// @TODO throw errors if health check requests fail, to log them in the Synchronizer
|
|
24
34
|
getSdkAPIHealthCheck: function () {
|
|
25
35
|
var url = "".concat(urls.sdk, "/version");
|
|
@@ -29,15 +39,6 @@ export function splitApiFactory(settings, platform, telemetryTracker) {
|
|
|
29
39
|
var url = "".concat(urls.events, "/version");
|
|
30
40
|
return splitHttpClient(url).then(function () { return true; }).catch(function () { return false; });
|
|
31
41
|
},
|
|
32
|
-
fetchAuth: function (userMatchingKeys) {
|
|
33
|
-
var url = "".concat(urls.auth, "/v2/auth?s=").concat(settings.sync.flagSpecVersion);
|
|
34
|
-
if (userMatchingKeys) { // `userMatchingKeys` is undefined in server-side
|
|
35
|
-
var queryParams = userMatchingKeys.map(userKeyToQueryParam).join('&');
|
|
36
|
-
if (queryParams)
|
|
37
|
-
url += '&' + queryParams;
|
|
38
|
-
}
|
|
39
|
-
return splitHttpClient(url, undefined, telemetryTracker.trackHttp(TOKEN));
|
|
40
|
-
},
|
|
41
42
|
fetchSplitChanges: function (since, noCache, till, rbSince) {
|
|
42
43
|
var url = "".concat(urls.sdk, "/splitChanges?s=").concat(settings.sync.flagSpecVersion, "&since=").concat(since).concat(rbSince ? '&rbSince=' + rbSince : '').concat(filterQueryString || '').concat(till ? '&till=' + till : '');
|
|
43
44
|
return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined, telemetryTracker.trackHttp(SPLITS))
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { __spreadArray } from "tslib";
|
|
2
2
|
// Dynamically require ioredis to prevent strict TypeScript binding
|
|
3
|
-
// and handle module export differences between v4 and
|
|
3
|
+
// and handle module export differences between v4 and later major versions.
|
|
4
4
|
var RedisConstructor;
|
|
5
5
|
try {
|
|
6
6
|
var ioredisLib = require('ioredis');
|
|
@@ -8,7 +8,7 @@ try {
|
|
|
8
8
|
}
|
|
9
9
|
catch (e) {
|
|
10
10
|
// If we reach here, the peer dependency is missing
|
|
11
|
-
throw new Error('ioredis is missing. Please install ioredis v4 or
|
|
11
|
+
throw new Error('ioredis is missing. Please install ioredis v4, v5 or v6.');
|
|
12
12
|
}
|
|
13
13
|
import { merge, isString } from '../../utils/lang';
|
|
14
14
|
import { thenable } from '../../utils/promise/thenable';
|
|
@@ -28,13 +28,16 @@ var DEFAULT_LIBRARY_OPTIONS = {
|
|
|
28
28
|
enableOfflineQueue: false,
|
|
29
29
|
connectTimeout: DEFAULT_OPTIONS.connectionTimeout,
|
|
30
30
|
lazyConnect: false,
|
|
31
|
-
// CRITICAL: v5
|
|
32
|
-
// v4 defaulted to 5000. We explicitly set it here to ensure v5
|
|
31
|
+
// CRITICAL: v5 and v6 default this to 0 (disabled), which breaks dynamic clusters.
|
|
32
|
+
// v4 defaulted to 5000. We explicitly set it here to ensure v5 and v6 work like v4.
|
|
33
33
|
slotsRefreshInterval: 5000,
|
|
34
|
+
// v6 defaults to RESP3 (`protocol: 3`). The SDK doesn't use any RESP3 feature,
|
|
35
|
+
// so we stick to RESP2 to keep the v4 and v5 behavior. Ignored by v4 and v5.
|
|
36
|
+
protocol: 2,
|
|
34
37
|
};
|
|
35
38
|
/**
|
|
36
39
|
* Redis adapter on top of the library of choice (written with ioredis) for some extra control.
|
|
37
|
-
* Refactored to use Composition instead of Inheritance to support
|
|
40
|
+
* Refactored to use Composition instead of Inheritance to support v4, v5 and v6.
|
|
38
41
|
*/
|
|
39
42
|
var RedisAdapter = /** @class */ (function () {
|
|
40
43
|
function RedisAdapter(log, storageSettings) {
|
|
@@ -5,92 +5,97 @@ import { getMatching } from '../../utils/key';
|
|
|
5
5
|
import { SDK_DEFINITIONS_ARRIVED, SDK_SEGMENTS_ARRIVED } from '../../readiness/constants';
|
|
6
6
|
import { POLLING_SMART_PAUSING, POLLING_START, POLLING_STOP } from '../../logger/constants';
|
|
7
7
|
import { usesSegmentsSync } from '../../storages/AbstractDefinitionsCacheSync';
|
|
8
|
+
import { splitChangesFetcherFactory } from './fetchers/splitChangesFetcher';
|
|
8
9
|
/**
|
|
9
10
|
* Expose start / stop mechanism for polling data from services.
|
|
10
11
|
* For client-side API with multiple clients.
|
|
11
12
|
*/
|
|
12
|
-
export function pollingManagerCSFactory(
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
if (mySegmentsSyncTask.isRunning())
|
|
28
|
-
mySegmentsSyncTask.stop();
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
// smart pausing
|
|
32
|
-
readiness.definitions.on(SDK_DEFINITIONS_ARRIVED, function () {
|
|
33
|
-
if (!definitionsSyncTask.isRunning())
|
|
34
|
-
return; // noop if not doing polling
|
|
35
|
-
var usingSegments = usesSegmentsSync(storage);
|
|
36
|
-
if (usingSegments !== mySegmentsSyncTask.isRunning()) {
|
|
37
|
-
log.info(POLLING_SMART_PAUSING, [usingSegments ? 'ON' : 'OFF']);
|
|
38
|
-
if (usingSegments) {
|
|
39
|
-
startMySegmentsSyncTasks();
|
|
40
|
-
}
|
|
41
|
-
else {
|
|
42
|
-
stopMySegmentsSyncTasks();
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
});
|
|
46
|
-
function add(matchingKey, readiness, storage) {
|
|
47
|
-
var mySegmentsSyncTask = mySegmentsSyncTaskFactory(serviceApi.fetchMemberships, storage, readiness, settings, matchingKey);
|
|
48
|
-
// smart ready
|
|
49
|
-
function smartReady(metadata) {
|
|
50
|
-
if (!readiness.isReady() && !usesSegmentsSync(storage))
|
|
51
|
-
readiness.segments.emit(SDK_SEGMENTS_ARRIVED, metadata);
|
|
13
|
+
export function pollingManagerCSFactory(definitionFetcherFactory) {
|
|
14
|
+
if (definitionFetcherFactory === void 0) { definitionFetcherFactory = splitChangesFetcherFactory; }
|
|
15
|
+
return function (params) {
|
|
16
|
+
var serviceApi = params.serviceApi, storage = params.storage, readiness = params.readiness, settings = params.settings;
|
|
17
|
+
var log = settings.log;
|
|
18
|
+
var definitionChangesFetcher = definitionFetcherFactory(params);
|
|
19
|
+
var definitionsSyncTask = definitionsSyncTaskFactory(definitionChangesFetcher, storage, readiness, settings);
|
|
20
|
+
// Map of matching keys to their corresponding MySegmentsSyncTask.
|
|
21
|
+
var mySegmentsSyncTasks = {};
|
|
22
|
+
var matchingKey = getMatching(settings.core.key);
|
|
23
|
+
var mySegmentsSyncTask = add(matchingKey, readiness, storage);
|
|
24
|
+
function startMySegmentsSyncTasks() {
|
|
25
|
+
forOwn(mySegmentsSyncTasks, function (mySegmentsSyncTask) {
|
|
26
|
+
mySegmentsSyncTask.start();
|
|
27
|
+
});
|
|
52
28
|
}
|
|
53
|
-
|
|
54
|
-
setTimeout(smartReady, 0);
|
|
55
|
-
else
|
|
56
|
-
readiness.definitions.once(SDK_DEFINITIONS_ARRIVED, smartReady);
|
|
57
|
-
mySegmentsSyncTasks[matchingKey] = mySegmentsSyncTask;
|
|
58
|
-
return mySegmentsSyncTask;
|
|
59
|
-
}
|
|
60
|
-
return {
|
|
61
|
-
definitionsSyncTask: definitionsSyncTask,
|
|
62
|
-
segmentsSyncTask: mySegmentsSyncTask,
|
|
63
|
-
// Start periodic fetching (polling)
|
|
64
|
-
start: function () {
|
|
65
|
-
log.info(POLLING_START);
|
|
66
|
-
definitionsSyncTask.start();
|
|
67
|
-
if (usesSegmentsSync(storage))
|
|
68
|
-
startMySegmentsSyncTasks();
|
|
69
|
-
},
|
|
70
|
-
// Stop periodic fetching (polling)
|
|
71
|
-
stop: function () {
|
|
72
|
-
log.info(POLLING_STOP);
|
|
73
|
-
if (definitionsSyncTask.isRunning())
|
|
74
|
-
definitionsSyncTask.stop();
|
|
75
|
-
stopMySegmentsSyncTasks();
|
|
76
|
-
},
|
|
77
|
-
// Used by SyncManager to know if running in polling mode.
|
|
78
|
-
isRunning: definitionsSyncTask.isRunning,
|
|
79
|
-
// fetch definitions and segments
|
|
80
|
-
syncAll: function () {
|
|
81
|
-
var promises = [definitionsSyncTask.execute()];
|
|
29
|
+
function stopMySegmentsSyncTasks() {
|
|
82
30
|
forOwn(mySegmentsSyncTasks, function (mySegmentsSyncTask) {
|
|
83
|
-
|
|
31
|
+
if (mySegmentsSyncTask.isRunning())
|
|
32
|
+
mySegmentsSyncTask.stop();
|
|
84
33
|
});
|
|
85
|
-
return Promise.all(promises);
|
|
86
|
-
},
|
|
87
|
-
// Support for handling mySegments sync of multiple clients
|
|
88
|
-
add: add,
|
|
89
|
-
remove: function (matchingKey) {
|
|
90
|
-
delete mySegmentsSyncTasks[matchingKey];
|
|
91
|
-
},
|
|
92
|
-
get: function (matchingKey) {
|
|
93
|
-
return mySegmentsSyncTasks[matchingKey];
|
|
94
34
|
}
|
|
35
|
+
// smart pausing
|
|
36
|
+
readiness.definitions.on(SDK_DEFINITIONS_ARRIVED, function () {
|
|
37
|
+
if (!definitionsSyncTask.isRunning())
|
|
38
|
+
return; // noop if not doing polling
|
|
39
|
+
var usingSegments = usesSegmentsSync(storage);
|
|
40
|
+
if (usingSegments !== mySegmentsSyncTask.isRunning()) {
|
|
41
|
+
log.info(POLLING_SMART_PAUSING, [usingSegments ? 'ON' : 'OFF']);
|
|
42
|
+
if (usingSegments) {
|
|
43
|
+
startMySegmentsSyncTasks();
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
stopMySegmentsSyncTasks();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
function add(matchingKey, readiness, storage) {
|
|
51
|
+
var mySegmentsSyncTask = mySegmentsSyncTaskFactory(serviceApi.fetchMemberships, storage, readiness, settings, matchingKey);
|
|
52
|
+
// smart ready
|
|
53
|
+
function smartReady(metadata) {
|
|
54
|
+
if (!readiness.isReady() && !usesSegmentsSync(storage))
|
|
55
|
+
readiness.segments.emit(SDK_SEGMENTS_ARRIVED, metadata);
|
|
56
|
+
}
|
|
57
|
+
if (!usesSegmentsSync(storage))
|
|
58
|
+
setTimeout(smartReady, 0);
|
|
59
|
+
else
|
|
60
|
+
readiness.definitions.once(SDK_DEFINITIONS_ARRIVED, smartReady);
|
|
61
|
+
mySegmentsSyncTasks[matchingKey] = mySegmentsSyncTask;
|
|
62
|
+
return mySegmentsSyncTask;
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
definitionsSyncTask: definitionsSyncTask,
|
|
66
|
+
segmentsSyncTask: mySegmentsSyncTask,
|
|
67
|
+
// Start periodic fetching (polling)
|
|
68
|
+
start: function () {
|
|
69
|
+
log.info(POLLING_START);
|
|
70
|
+
definitionsSyncTask.start();
|
|
71
|
+
if (usesSegmentsSync(storage))
|
|
72
|
+
startMySegmentsSyncTasks();
|
|
73
|
+
},
|
|
74
|
+
// Stop periodic fetching (polling)
|
|
75
|
+
stop: function () {
|
|
76
|
+
log.info(POLLING_STOP);
|
|
77
|
+
if (definitionsSyncTask.isRunning())
|
|
78
|
+
definitionsSyncTask.stop();
|
|
79
|
+
stopMySegmentsSyncTasks();
|
|
80
|
+
},
|
|
81
|
+
// Used by SyncManager to know if running in polling mode.
|
|
82
|
+
isRunning: definitionsSyncTask.isRunning,
|
|
83
|
+
// fetch definitions and segments
|
|
84
|
+
syncAll: function () {
|
|
85
|
+
var promises = [definitionsSyncTask.execute()];
|
|
86
|
+
forOwn(mySegmentsSyncTasks, function (mySegmentsSyncTask) {
|
|
87
|
+
promises.push(mySegmentsSyncTask.execute());
|
|
88
|
+
});
|
|
89
|
+
return Promise.all(promises);
|
|
90
|
+
},
|
|
91
|
+
// Support for handling mySegments sync of multiple clients
|
|
92
|
+
add: add,
|
|
93
|
+
remove: function (matchingKey) {
|
|
94
|
+
delete mySegmentsSyncTasks[matchingKey];
|
|
95
|
+
},
|
|
96
|
+
get: function (matchingKey) {
|
|
97
|
+
return mySegmentsSyncTasks[matchingKey];
|
|
98
|
+
}
|
|
99
|
+
};
|
|
95
100
|
};
|
|
96
101
|
}
|
|
@@ -1,45 +1,53 @@
|
|
|
1
1
|
import { definitionsSyncTaskFactory } from './syncTasks/definitionsSyncTask';
|
|
2
2
|
import { segmentsSyncTaskFactory } from './syncTasks/segmentsSyncTask';
|
|
3
3
|
import { POLLING_START, POLLING_STOP, LOG_PREFIX_SYNC_POLLING } from '../../logger/constants';
|
|
4
|
+
import { segmentChangesFetcherFactory } from './fetchers/segmentChangesFetcher';
|
|
5
|
+
import { splitChangesFetcherFactory } from './fetchers/splitChangesFetcher';
|
|
4
6
|
/**
|
|
5
7
|
* Expose start / stop mechanism for pulling data from services.
|
|
6
8
|
*/
|
|
7
|
-
export function pollingManagerSSFactory(
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
9
|
+
export function pollingManagerSSFactory(definitionFetcherFactory, segmentFetcherFactory) {
|
|
10
|
+
if (definitionFetcherFactory === void 0) { definitionFetcherFactory = splitChangesFetcherFactory; }
|
|
11
|
+
if (segmentFetcherFactory === void 0) { segmentFetcherFactory = function (params) { return segmentChangesFetcherFactory(params.serviceApi.fetchSegmentChanges); }; }
|
|
12
|
+
return function (params) {
|
|
13
|
+
var storage = params.storage, readiness = params.readiness, settings = params.settings;
|
|
14
|
+
var log = settings.log;
|
|
15
|
+
var definitionChangesFetcher = definitionFetcherFactory(params);
|
|
16
|
+
var segmentChangesFetcher = segmentFetcherFactory(params);
|
|
17
|
+
var segmentsSyncTask = segmentsSyncTaskFactory(segmentChangesFetcher, storage, readiness, settings);
|
|
18
|
+
var definitionsSyncTask = definitionsSyncTaskFactory(definitionChangesFetcher, storage, readiness, settings, segmentsSyncTask);
|
|
19
|
+
return {
|
|
20
|
+
definitionsSyncTask: definitionsSyncTask,
|
|
21
|
+
segmentsSyncTask: segmentsSyncTask,
|
|
22
|
+
// Start periodic fetching (polling)
|
|
23
|
+
start: function () {
|
|
24
|
+
log.info(POLLING_START);
|
|
25
|
+
log.debug(LOG_PREFIX_SYNC_POLLING + "".concat(definitionChangesFetcher.type, " will be refreshed each ").concat(settings.scheduler.featuresRefreshRate, " millis"));
|
|
26
|
+
log.debug(LOG_PREFIX_SYNC_POLLING + "segments will be refreshed each ".concat(settings.scheduler.segmentsRefreshRate, " millis"));
|
|
27
|
+
var startingUp = definitionsSyncTask.start();
|
|
28
|
+
if (startingUp) {
|
|
29
|
+
startingUp.then(function () {
|
|
30
|
+
if (definitionsSyncTask.isRunning())
|
|
31
|
+
segmentsSyncTask.start();
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
// Stop periodic fetching (polling)
|
|
36
|
+
stop: function () {
|
|
37
|
+
log.info(POLLING_STOP);
|
|
38
|
+
if (definitionsSyncTask.isRunning())
|
|
39
|
+
definitionsSyncTask.stop();
|
|
40
|
+
if (segmentsSyncTask.isRunning())
|
|
41
|
+
segmentsSyncTask.stop();
|
|
42
|
+
},
|
|
43
|
+
// Used by SyncManager to know if running in polling mode.
|
|
44
|
+
isRunning: definitionsSyncTask.isRunning,
|
|
45
|
+
syncAll: function () {
|
|
46
|
+
// fetch definitions and segments. There is no need to catch this promise (`DefinitionChangesUpdater` is always resolved with a boolean value)
|
|
47
|
+
return definitionsSyncTask.execute().then(function () {
|
|
48
|
+
return segmentsSyncTask.execute();
|
|
25
49
|
});
|
|
26
50
|
}
|
|
27
|
-
}
|
|
28
|
-
// Stop periodic fetching (polling)
|
|
29
|
-
stop: function () {
|
|
30
|
-
log.info(POLLING_STOP);
|
|
31
|
-
if (definitionsSyncTask.isRunning())
|
|
32
|
-
definitionsSyncTask.stop();
|
|
33
|
-
if (segmentsSyncTask.isRunning())
|
|
34
|
-
segmentsSyncTask.stop();
|
|
35
|
-
},
|
|
36
|
-
// Used by SyncManager to know if running in polling mode.
|
|
37
|
-
isRunning: definitionsSyncTask.isRunning,
|
|
38
|
-
syncAll: function () {
|
|
39
|
-
// fetch definitions and segments. There is no need to catch this promise (`DefinitionChangesUpdater` is always resolved with a boolean value)
|
|
40
|
-
return definitionsSyncTask.execute().then(function () {
|
|
41
|
-
return segmentsSyncTask.execute();
|
|
42
|
-
});
|
|
43
|
-
}
|
|
51
|
+
};
|
|
44
52
|
};
|
|
45
53
|
}
|
|
@@ -4,7 +4,7 @@ import { SYNC_FETCH, SYNC_UPDATE, SYNC_FETCH_FAILS, SYNC_FETCH_RETRY } from '../
|
|
|
4
4
|
import { startsWith } from '../../../utils/lang';
|
|
5
5
|
import { IN_RULE_BASED_SEGMENT, IN_SEGMENT, RULE_BASED_SEGMENT, STANDARD_SEGMENT } from '../../../utils/constants';
|
|
6
6
|
import { setToArray } from '../../../utils/lang/sets';
|
|
7
|
-
import {
|
|
7
|
+
import { RB_SEGMENT_UPDATE } from '../../streaming/constants';
|
|
8
8
|
/**
|
|
9
9
|
* Collect segments from a raw FF or RBS definition.
|
|
10
10
|
* Exported for testing purposes.
|
|
@@ -120,14 +120,14 @@ export function definitionChangesUpdaterFactory(log, definitionChangesFetcher, s
|
|
|
120
120
|
var since = sinces[0], rbSince = sinces[1];
|
|
121
121
|
log.debug(SYNC_FETCH, [definitionChangesFetcher.type, since, rbSince]);
|
|
122
122
|
return Promise.resolve(instantUpdate ?
|
|
123
|
-
instantUpdate.type ===
|
|
123
|
+
instantUpdate.type === RB_SEGMENT_UPDATE ?
|
|
124
|
+
{ rbs: convertInstantUpdateToDefinitionChanges(instantUpdate) } :
|
|
124
125
|
// IFFU edge case: a change to definition that adds an IN_RULE_BASED_SEGMENT matcher that is not present yet
|
|
125
126
|
Promise.resolve(rbSegments.contains(parseSegments(instantUpdate.payload, IN_RULE_BASED_SEGMENT))).then(function (contains) {
|
|
126
127
|
return contains ?
|
|
127
128
|
{ d: convertInstantUpdateToDefinitionChanges(instantUpdate) } :
|
|
128
129
|
definitionChangesFetcher(since, noCache, till, rbSince, _promiseDecorator);
|
|
129
130
|
}) :
|
|
130
|
-
{ rbs: convertInstantUpdateToDefinitionChanges(instantUpdate) } :
|
|
131
131
|
definitionChangesFetcher(since, noCache, till, rbSince, _promiseDecorator))
|
|
132
132
|
.then(function (definitionChanges) {
|
|
133
133
|
var usedSegments = new Set();
|
|
@@ -28,7 +28,7 @@ export function segmentChangesUpdaterFactory(log, segmentChangesFetcher, segment
|
|
|
28
28
|
false :
|
|
29
29
|
segmentChangesFetcher(since || -1, segmentName, noCache, till, _promiseDecorator).then(function (changes) {
|
|
30
30
|
return Promise.all(changes.map(function (x) {
|
|
31
|
-
log.debug("".concat(LOG_PREFIX_SYNC, "Processing ").concat(segmentName, " with till = ").concat(x.till, ". Added: ").concat(x.added.length, ". Removed: ").concat(x.removed.length));
|
|
31
|
+
log.debug("".concat(LOG_PREFIX_SYNC, "Processing ").concat(segmentName, " with since = ").concat(x.since, " and till = ").concat(x.till, ". Added: ").concat(x.added.length, ". Removed: ").concat(x.removed.length));
|
|
32
32
|
return segments.update(segmentName, x.added, x.removed, x.till);
|
|
33
33
|
})).then(function (updates) {
|
|
34
34
|
return updates.some(function (update) { return update; });
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import { objectAssign } from '../../../utils/lang/objectAssign';
|
|
2
|
-
import { encodeToBase64 } from '../../../utils/base64';
|
|
3
2
|
import { decodeJWTtoken } from '../../../utils/jwt';
|
|
4
|
-
import { hash } from '../../../utils/murmur3/murmur3';
|
|
5
3
|
/**
|
|
6
4
|
* Factory of authentication function.
|
|
7
5
|
*
|
|
8
|
-
* @param fetchAuth -
|
|
6
|
+
* @param fetchAuth - /auth endpoint
|
|
9
7
|
*/
|
|
10
|
-
export function
|
|
8
|
+
export function fetchAuthFactory(fetchAuth) {
|
|
11
9
|
/**
|
|
12
10
|
* Run authentication requests to Auth Server, and returns a promise that resolves with the decoded JTW token.
|
|
13
11
|
* @param userKeys - set of user Keys to track membership updates. It is undefined for server-side API.
|
|
@@ -21,18 +19,20 @@ export function authenticateFactory(fetchAuth) {
|
|
|
21
19
|
if (typeof decodedToken.iat !== 'number' || typeof decodedToken.exp !== 'number')
|
|
22
20
|
throw new Error('token properties "issuedAt" (iat) or "expiration" (exp) are missing or invalid');
|
|
23
21
|
var channels = JSON.parse(decodedToken['x-ably-capability']);
|
|
24
|
-
|
|
22
|
+
var credential = objectAssign({
|
|
25
23
|
decodedToken: decodedToken,
|
|
26
24
|
channels: channels
|
|
27
25
|
}, json);
|
|
26
|
+
// The `/api/v3/auth` endpoint nests the streaming settings under `config.streaming`. Normalize
|
|
27
|
+
// them into the flat `pushEnabled`/`connDelay` properties used by the PushManager.
|
|
28
|
+
var streaming = credential.config && credential.config.streaming;
|
|
29
|
+
if (streaming) {
|
|
30
|
+
credential.pushEnabled = streaming.enabled;
|
|
31
|
+
credential.connDelay = streaming.delay;
|
|
32
|
+
}
|
|
33
|
+
return credential;
|
|
28
34
|
}
|
|
29
35
|
return json;
|
|
30
36
|
});
|
|
31
37
|
};
|
|
32
38
|
}
|
|
33
|
-
/**
|
|
34
|
-
* Returns the hash of a given user key
|
|
35
|
-
*/
|
|
36
|
-
export function hashUserKey(userKey) {
|
|
37
|
-
return encodeToBase64(hash(userKey, 0).toString());
|
|
38
|
-
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { errorParser, messageParser } from './NotificationParser';
|
|
2
2
|
import { notificationKeeperFactory } from './NotificationKeeper';
|
|
3
|
-
import { PUSH_RETRYABLE_ERROR, PUSH_NON_RETRYABLE_ERROR, OCCUPANCY, CONTROL, SEGMENT_UPDATE, SPLIT_KILL, SPLIT_UPDATE, MEMBERSHIPS_MS_UPDATE, MEMBERSHIPS_LS_UPDATE, RB_SEGMENT_UPDATE } from '../constants';
|
|
3
|
+
import { PUSH_RETRYABLE_ERROR, PUSH_NON_RETRYABLE_ERROR, OCCUPANCY, CONTROL, SEGMENT_UPDATE, SPLIT_KILL, SPLIT_UPDATE, CONFIG_UPDATE, MEMBERSHIPS_MS_UPDATE, MEMBERSHIPS_LS_UPDATE, RB_SEGMENT_UPDATE } from '../constants';
|
|
4
4
|
import { STREAMING_PARSING_ERROR_FAILS, ERROR_STREAMING_SSE, STREAMING_PARSING_MESSAGE_FAILS, STREAMING_NEW_MESSAGE } from '../../../logger/constants';
|
|
5
5
|
import { ABLY_ERROR, NON_REQUESTED, SSE_CONNECTION_ERROR } from '../../../utils/constants';
|
|
6
6
|
/**
|
|
@@ -71,6 +71,7 @@ export function SSEHandlerFactory(log, pushEmitter, telemetryTracker) {
|
|
|
71
71
|
switch (parsedData.type) {
|
|
72
72
|
/* update events */
|
|
73
73
|
case SPLIT_UPDATE:
|
|
74
|
+
case CONFIG_UPDATE:
|
|
74
75
|
case SEGMENT_UPDATE:
|
|
75
76
|
case MEMBERSHIPS_MS_UPDATE:
|
|
76
77
|
case MEMBERSHIPS_LS_UPDATE:
|
|
@@ -27,6 +27,7 @@ export var MEMBERSHIPS_LS_UPDATE = 'MEMBERSHIPS_LS_UPDATE';
|
|
|
27
27
|
export var SEGMENT_UPDATE = 'SEGMENT_UPDATE';
|
|
28
28
|
export var SPLIT_KILL = 'SPLIT_KILL';
|
|
29
29
|
export var SPLIT_UPDATE = 'SPLIT_UPDATE';
|
|
30
|
+
export var CONFIG_UPDATE = 'CONFIG_UPDATE';
|
|
30
31
|
export var RB_SEGMENT_UPDATE = 'RB_SEGMENT_UPDATE';
|
|
31
32
|
// Control-type push notifications, handled by NotificationKeeper
|
|
32
33
|
export var CONTROL = 'CONTROL';
|
|
@@ -4,11 +4,10 @@ import { SSEHandlerFactory } from './SSEHandler';
|
|
|
4
4
|
import { MySegmentsUpdateWorker } from './UpdateWorkers/MySegmentsUpdateWorker';
|
|
5
5
|
import { SegmentsUpdateWorker } from './UpdateWorkers/SegmentsUpdateWorker';
|
|
6
6
|
import { DefinitionsUpdateWorker } from './UpdateWorkers/DefinitionsUpdateWorker';
|
|
7
|
-
import { authenticateFactory, hashUserKey } from './AuthClient';
|
|
8
7
|
import { forOwn } from '../../utils/lang';
|
|
9
8
|
import { SSEClient } from './SSEClient';
|
|
10
9
|
import { checkIfServerSide, getMatching } from '../../utils/key';
|
|
11
|
-
import { MEMBERSHIPS_MS_UPDATE, MEMBERSHIPS_LS_UPDATE, PUSH_NON_RETRYABLE_ERROR, PUSH_SUBSYSTEM_DOWN, SECONDS_BEFORE_EXPIRATION, SEGMENT_UPDATE, SPLIT_KILL, SPLIT_UPDATE, RB_SEGMENT_UPDATE, PUSH_RETRYABLE_ERROR, PUSH_SUBSYSTEM_UP, ControlType } from './constants';
|
|
10
|
+
import { MEMBERSHIPS_MS_UPDATE, MEMBERSHIPS_LS_UPDATE, PUSH_NON_RETRYABLE_ERROR, PUSH_SUBSYSTEM_DOWN, SECONDS_BEFORE_EXPIRATION, SEGMENT_UPDATE, SPLIT_KILL, SPLIT_UPDATE, CONFIG_UPDATE, RB_SEGMENT_UPDATE, PUSH_RETRYABLE_ERROR, PUSH_SUBSYSTEM_UP, ControlType } from './constants';
|
|
12
11
|
import { STREAMING_FALLBACK, STREAMING_REFRESH_TOKEN, STREAMING_CONNECTING, STREAMING_DISABLED, ERROR_STREAMING_AUTH, STREAMING_DISCONNECTING, STREAMING_RECONNECT, STREAMING_PARSING_MEMBERSHIPS_UPDATE } from '../../logger/constants';
|
|
13
12
|
import { UpdateStrategy } from './SSEHandler/types';
|
|
14
13
|
import { getDelay, isInBitmap, parseBitmap, parseCompressedData } from './parseUtils';
|
|
@@ -34,7 +33,6 @@ export function pushManagerFactory(params, pollingManager) {
|
|
|
34
33
|
log.warn(STREAMING_FALLBACK, [e]);
|
|
35
34
|
return;
|
|
36
35
|
}
|
|
37
|
-
var authenticate = authenticateFactory(serviceApi.fetchAuth);
|
|
38
36
|
// init feedback loop
|
|
39
37
|
var pushEmitter = new platform.EventEmitter();
|
|
40
38
|
var sseHandler = SSEHandlerFactory(log, pushEmitter, telemetryTracker);
|
|
@@ -44,8 +42,6 @@ export function pushManagerFactory(params, pollingManager) {
|
|
|
44
42
|
var segmentsUpdateWorker = userKey ? undefined : SegmentsUpdateWorker(log, pollingManager.segmentsSyncTask, storage.segments);
|
|
45
43
|
// For server-side we pass the segmentsSyncTask, used by DefinitionsUpdateWorker to fetch new segments
|
|
46
44
|
var definitionsUpdateWorker = DefinitionsUpdateWorker(log, storage, pollingManager.definitionsSyncTask, readiness.definitions, telemetryTracker);
|
|
47
|
-
// [Only for client-side] map of hashes to user keys, to dispatch membership update events to the corresponding MySegmentsUpdateWorker
|
|
48
|
-
var userKeyHashes = {};
|
|
49
45
|
// [Only for client-side] map of user keys to their corresponding hash64 and MySegmentsUpdateWorkers.
|
|
50
46
|
// Hash64 is used to process membership update events and dispatch actions to the corresponding MySegmentsUpdateWorker.
|
|
51
47
|
var clients = {};
|
|
@@ -90,7 +86,7 @@ export function pushManagerFactory(params, pollingManager) {
|
|
|
90
86
|
log.info(STREAMING_CONNECTING);
|
|
91
87
|
disconnected = false;
|
|
92
88
|
var userKeys = userKey ? Object.keys(clients) : undefined;
|
|
93
|
-
|
|
89
|
+
serviceApi.fetchAuth(userKeys).then(function (authData) {
|
|
94
90
|
if (disconnected)
|
|
95
91
|
return;
|
|
96
92
|
// 'pushEnabled: false' is handled as a PUSH_NON_RETRYABLE_ERROR instead of PUSH_SUBSYSTEM_DOWN, in order to
|
|
@@ -178,8 +174,11 @@ export function pushManagerFactory(params, pollingManager) {
|
|
|
178
174
|
connectPush();
|
|
179
175
|
});
|
|
180
176
|
/** Functions related to synchronization (Queues and Workers in the spec) */
|
|
177
|
+
// Some notification types are specific to the Feature flags or Configs SDKs. Their handlers are
|
|
178
|
+
// registered unconditionally, since the SDK only subscribes to the channels of its own entities.
|
|
181
179
|
pushEmitter.on(SPLIT_KILL, definitionsUpdateWorker.killDefinition);
|
|
182
180
|
pushEmitter.on(SPLIT_UPDATE, definitionsUpdateWorker.put);
|
|
181
|
+
pushEmitter.on(CONFIG_UPDATE, definitionsUpdateWorker.put);
|
|
183
182
|
pushEmitter.on(RB_SEGMENT_UPDATE, definitionsUpdateWorker.put);
|
|
184
183
|
function handleMySegmentsUpdate(parsedData) {
|
|
185
184
|
switch (parsedData.u) {
|
|
@@ -282,9 +281,7 @@ export function pushManagerFactory(params, pollingManager) {
|
|
|
282
281
|
},
|
|
283
282
|
// [Only for client-side]
|
|
284
283
|
add: function (userKey, mySegmentsSyncTask) {
|
|
285
|
-
|
|
286
|
-
if (!userKeyHashes[hash]) {
|
|
287
|
-
userKeyHashes[hash] = userKey;
|
|
284
|
+
if (!clients[userKey]) {
|
|
288
285
|
clients[userKey] = {
|
|
289
286
|
hash64: hash64(userKey),
|
|
290
287
|
worker: MySegmentsUpdateWorker(log, storage, mySegmentsSyncTask, telemetryTracker)
|
|
@@ -305,8 +302,6 @@ export function pushManagerFactory(params, pollingManager) {
|
|
|
305
302
|
},
|
|
306
303
|
// [Only for client-side]
|
|
307
304
|
remove: function (userKey) {
|
|
308
|
-
var hash = hashUserKey(userKey);
|
|
309
|
-
delete userKeyHashes[hash];
|
|
310
305
|
delete clients[userKey];
|
|
311
306
|
}
|
|
312
307
|
});
|