@splitsoftware/splitio-commons 3.1.1-rc.10 → 3.1.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/CHANGES.txt +3 -0
- package/cjs/evaluator/condition/index.js +2 -2
- package/cjs/evaluator/fallbackTreatmentsCalculator/fallbackSanitizer/index.js +5 -8
- package/cjs/evaluator/index.js +81 -71
- package/cjs/listeners/browser.js +2 -1
- package/cjs/listeners/node.js +4 -4
- package/cjs/logger/constants.js +15 -20
- package/cjs/logger/messages/debug.js +5 -6
- package/cjs/logger/messages/error.js +3 -3
- package/cjs/logger/messages/info.js +3 -4
- package/cjs/logger/messages/warn.js +6 -7
- package/cjs/platform/browser.js +15 -0
- package/cjs/platform/getEventSource/browser.js +8 -0
- package/cjs/platform/getEventSource/eventsource.js +480 -0
- package/cjs/platform/getEventSource/node.js +26 -0
- package/cjs/platform/getFetch/browser.js +9 -0
- package/cjs/platform/getFetch/node.js +27 -0
- package/cjs/platform/getOptions/node.js +25 -0
- package/cjs/platform/node.js +17 -0
- package/cjs/presets/serverSide.js +2 -2
- package/cjs/readiness/constants.js +5 -4
- package/cjs/readiness/readinessManager.js +23 -23
- package/cjs/readiness/sdkReadinessManager.js +1 -17
- package/cjs/sdkClient/client.js +24 -50
- package/cjs/sdkClient/clientInputValidation.js +6 -17
- package/cjs/sdkClient/sdkClient.js +3 -60
- package/cjs/sdkClient/sdkLifecycle.js +74 -0
- package/cjs/sdkClient/trackMethod.js +56 -0
- package/cjs/sdkFactory/index.js +11 -15
- package/cjs/sdkManager/index.js +5 -5
- package/cjs/services/authProvider.js +80 -0
- package/cjs/services/decorateHeaders.js +2 -1
- package/cjs/{sync/streaming/AuthClient/index.js → services/fetchAuth.js} +15 -16
- package/cjs/services/secureSplitHttpClient.js +36 -0
- package/cjs/services/serviceApi.js +147 -0
- package/cjs/services/splitApi.js +24 -10
- package/cjs/services/splitHttpClient.js +3 -5
- package/cjs/storages/AbstractDefinitionsCacheAsync.js +51 -0
- package/cjs/storages/AbstractDefinitionsCacheSync.js +76 -0
- package/cjs/storages/KeyBuilder.js +6 -6
- package/cjs/storages/KeyBuilderCS.js +5 -5
- package/cjs/storages/KeyBuilderSS.js +2 -2
- package/cjs/storages/getRolloutPlan.js +3 -3
- package/cjs/storages/inLocalStorage/DefinitionsCacheInLocal.js +195 -0
- package/cjs/storages/inLocalStorage/MySegmentsCacheInLocal.js +1 -2
- package/cjs/storages/inLocalStorage/RBSegmentsCacheInLocal.js +12 -11
- package/cjs/storages/inLocalStorage/index.js +6 -6
- package/cjs/storages/inLocalStorage/validateCache.js +3 -3
- package/cjs/storages/inMemory/DefinitionsCacheInMemory.js +122 -0
- package/cjs/storages/inMemory/InMemoryStorage.js +4 -4
- package/cjs/storages/inMemory/InMemoryStorageCS.js +5 -5
- package/cjs/storages/inMemory/RBSegmentsCacheInMemory.js +7 -6
- package/cjs/storages/inMemory/SegmentsCacheInMemory.js +1 -1
- package/cjs/storages/inMemory/TelemetryCacheInMemory.js +5 -5
- package/cjs/storages/inRedis/{SplitsCacheInRedis.js → DefinitionsCacheInRedis.js} +79 -77
- package/cjs/storages/inRedis/RBSegmentsCacheInRedis.js +4 -2
- package/cjs/storages/inRedis/index.js +2 -2
- package/cjs/storages/pluggable/DefinitionsCachePluggable.js +214 -0
- package/cjs/storages/pluggable/RBSegmentsCachePluggable.js +4 -2
- package/cjs/storages/pluggable/index.js +2 -2
- package/cjs/storages/setRolloutPlan.js +4 -4
- package/cjs/storages/utils.js +1 -0
- package/cjs/sync/offline/syncTasks/fromObjectSyncTask.js +5 -5
- package/cjs/sync/polling/fetchers/splitChangesFetcher.js +24 -15
- package/cjs/sync/polling/pollingManagerCS.js +86 -81
- package/cjs/sync/polling/pollingManagerSS.js +44 -36
- package/cjs/sync/polling/syncTasks/definitionsSyncTask.js +13 -0
- package/cjs/sync/polling/syncTasks/segmentsSyncTask.js +2 -3
- package/cjs/sync/polling/updaters/definitionChangesUpdater.js +207 -0
- package/cjs/sync/polling/updaters/mySegmentsUpdater.js +3 -3
- package/cjs/sync/polling/updaters/segmentChangesUpdater.js +6 -6
- package/cjs/sync/streaming/SSEHandler/NotificationKeeper.js +1 -1
- package/cjs/sync/streaming/SSEHandler/index.js +2 -1
- package/cjs/sync/streaming/UpdateWorkers/{SplitsUpdateWorker.js → DefinitionsUpdateWorker.js} +19 -20
- package/cjs/sync/streaming/constants.js +4 -3
- package/cjs/sync/streaming/parseUtils.js +14 -14
- package/cjs/sync/streaming/pushManager.js +22 -26
- package/cjs/sync/submitters/eventsSubmitter.js +1 -1
- package/cjs/sync/submitters/impressionCountsSubmitter.js +1 -1
- package/cjs/sync/submitters/impressionsSubmitter.js +5 -4
- package/cjs/sync/submitters/telemetrySubmitter.js +3 -4
- package/cjs/sync/submitters/uniqueKeysSubmitter.js +1 -1
- package/cjs/sync/syncManagerOnline.js +5 -5
- package/cjs/utils/Backoff.js +35 -3
- package/cjs/utils/EventEmitter.js +391 -0
- package/cjs/utils/filter/bloomFilter.js +37 -0
- package/cjs/utils/inputValidation/{split.js → definition.js} +10 -10
- package/cjs/utils/inputValidation/{splitExistence.js → definitionExistence.js} +6 -6
- package/cjs/utils/inputValidation/definitions.js +25 -0
- package/cjs/utils/inputValidation/index.js +7 -7
- package/cjs/utils/inputValidation/isOperational.js +4 -4
- package/cjs/utils/inputValidation/target.js +22 -0
- package/cjs/utils/labels/index.js +3 -3
- package/cjs/utils/settingsValidation/index.js +2 -0
- package/cjs/utils/settingsValidation/splitFilters.js +3 -3
- package/cjs/utils/settingsValidation/url.js +6 -2
- package/esm/evaluator/condition/index.js +2 -2
- package/esm/evaluator/fallbackTreatmentsCalculator/fallbackSanitizer/index.js +5 -8
- package/esm/evaluator/index.js +80 -71
- package/esm/listeners/browser.js +2 -1
- package/esm/listeners/node.js +4 -4
- package/esm/logger/constants.js +12 -17
- package/esm/logger/messages/debug.js +5 -6
- package/esm/logger/messages/error.js +3 -3
- package/esm/logger/messages/info.js +3 -4
- package/esm/logger/messages/warn.js +6 -7
- package/esm/platform/browser.js +12 -0
- package/esm/platform/getEventSource/browser.js +4 -0
- package/esm/platform/getEventSource/eventsource.js +480 -0
- package/esm/platform/getEventSource/node.js +20 -0
- package/esm/platform/getFetch/browser.js +5 -0
- package/esm/platform/getFetch/node.js +22 -0
- package/esm/platform/getOptions/node.js +20 -0
- package/esm/platform/node.js +14 -0
- package/esm/presets/serverSide.js +2 -2
- package/esm/readiness/constants.js +4 -3
- package/esm/readiness/readinessManager.js +24 -24
- package/esm/readiness/sdkReadinessManager.js +2 -18
- package/esm/sdkClient/client.js +23 -50
- package/esm/sdkClient/clientInputValidation.js +8 -19
- package/esm/sdkClient/sdkClient.js +3 -60
- package/esm/sdkClient/sdkLifecycle.js +70 -0
- package/esm/sdkClient/trackMethod.js +52 -0
- package/esm/sdkFactory/index.js +12 -16
- package/esm/sdkManager/index.js +6 -6
- package/esm/services/authProvider.js +76 -0
- package/esm/services/decorateHeaders.js +2 -1
- package/esm/{sync/streaming/AuthClient/index.js → services/fetchAuth.js} +13 -13
- package/esm/services/secureSplitHttpClient.js +32 -0
- package/esm/services/serviceApi.js +143 -0
- package/esm/services/splitApi.js +24 -10
- package/esm/services/splitHttpClient.js +3 -5
- package/esm/storages/AbstractDefinitionsCacheAsync.js +48 -0
- package/esm/storages/AbstractDefinitionsCacheSync.js +71 -0
- package/esm/storages/KeyBuilder.js +6 -6
- package/esm/storages/KeyBuilderCS.js +5 -5
- package/esm/storages/KeyBuilderSS.js +2 -2
- package/esm/storages/getRolloutPlan.js +3 -3
- package/esm/storages/inLocalStorage/DefinitionsCacheInLocal.js +192 -0
- package/esm/storages/inLocalStorage/MySegmentsCacheInLocal.js +1 -2
- package/esm/storages/inLocalStorage/RBSegmentsCacheInLocal.js +9 -8
- package/esm/storages/inLocalStorage/index.js +6 -6
- package/esm/storages/inLocalStorage/validateCache.js +3 -3
- package/esm/storages/inMemory/DefinitionsCacheInMemory.js +119 -0
- package/esm/storages/inMemory/InMemoryStorage.js +4 -4
- package/esm/storages/inMemory/InMemoryStorageCS.js +5 -5
- package/esm/storages/inMemory/RBSegmentsCacheInMemory.js +4 -3
- package/esm/storages/inMemory/SegmentsCacheInMemory.js +1 -1
- package/esm/storages/inMemory/TelemetryCacheInMemory.js +5 -5
- package/esm/storages/inRedis/{SplitsCacheInRedis.js → DefinitionsCacheInRedis.js} +78 -76
- package/esm/storages/inRedis/RBSegmentsCacheInRedis.js +4 -2
- package/esm/storages/inRedis/index.js +2 -2
- package/esm/storages/pluggable/DefinitionsCachePluggable.js +211 -0
- package/esm/storages/pluggable/RBSegmentsCachePluggable.js +4 -2
- package/esm/storages/pluggable/index.js +2 -2
- package/esm/storages/setRolloutPlan.js +4 -4
- package/esm/storages/utils.js +1 -0
- package/esm/sync/offline/syncTasks/fromObjectSyncTask.js +6 -6
- package/esm/sync/polling/fetchers/splitChangesFetcher.js +25 -16
- package/esm/sync/polling/pollingManagerCS.js +87 -82
- package/esm/sync/polling/pollingManagerSS.js +44 -36
- package/esm/sync/polling/syncTasks/definitionsSyncTask.js +9 -0
- package/esm/sync/polling/syncTasks/segmentsSyncTask.js +2 -3
- package/esm/sync/polling/updaters/definitionChangesUpdater.js +201 -0
- package/esm/sync/polling/updaters/mySegmentsUpdater.js +3 -3
- package/esm/sync/polling/updaters/segmentChangesUpdater.js +7 -7
- package/esm/sync/streaming/SSEHandler/NotificationKeeper.js +2 -2
- package/esm/sync/streaming/SSEHandler/index.js +3 -2
- package/esm/sync/streaming/UpdateWorkers/{SplitsUpdateWorker.js → DefinitionsUpdateWorker.js} +19 -20
- package/esm/sync/streaming/constants.js +3 -2
- package/esm/sync/streaming/parseUtils.js +11 -11
- package/esm/sync/streaming/pushManager.js +24 -28
- package/esm/sync/submitters/eventsSubmitter.js +1 -1
- package/esm/sync/submitters/impressionCountsSubmitter.js +1 -1
- package/esm/sync/submitters/impressionsSubmitter.js +5 -4
- package/esm/sync/submitters/telemetrySubmitter.js +3 -4
- package/esm/sync/submitters/uniqueKeysSubmitter.js +1 -1
- package/esm/sync/syncManagerOnline.js +4 -4
- package/esm/utils/Backoff.js +35 -3
- package/esm/utils/EventEmitter.js +387 -0
- package/esm/utils/filter/bloomFilter.js +33 -0
- package/esm/utils/inputValidation/{split.js → definition.js} +8 -8
- package/esm/utils/inputValidation/definitionExistence.js +15 -0
- package/esm/utils/inputValidation/definitions.js +21 -0
- package/esm/utils/inputValidation/index.js +3 -3
- package/esm/utils/inputValidation/isOperational.js +4 -4
- package/esm/utils/inputValidation/target.js +18 -0
- package/esm/utils/labels/index.js +2 -2
- package/esm/utils/settingsValidation/index.js +2 -0
- package/esm/utils/settingsValidation/splitFilters.js +3 -3
- package/esm/utils/settingsValidation/url.js +6 -2
- package/package.json +1 -1
- package/src/dtos/types.ts +4 -4
- package/src/services/authProvider.ts +2 -2
- package/src/{sync/streaming/AuthClient/index.ts → services/fetchAuth.ts} +3 -4
- package/src/services/splitApi.ts +1 -1
- package/src/services/types.ts +21 -4
- package/src/storages/AbstractDefinitionsCacheAsync.ts +3 -3
- package/src/storages/AbstractDefinitionsCacheSync.ts +2 -2
- package/src/storages/inLocalStorage/DefinitionsCacheInLocal.ts +2 -2
- package/src/storages/inLocalStorage/RBSegmentsCacheInLocal.ts +3 -3
- package/src/storages/inMemory/DefinitionsCacheInMemory.ts +2 -2
- package/src/storages/inMemory/RBSegmentsCacheInMemory.ts +2 -2
- package/src/storages/inRedis/DefinitionsCacheInRedis.ts +6 -4
- package/src/storages/inRedis/RBSegmentsCacheInRedis.ts +7 -5
- package/src/storages/pluggable/DefinitionsCachePluggable.ts +4 -2
- package/src/storages/pluggable/RBSegmentsCachePluggable.ts +5 -3
- package/src/storages/types.ts +6 -6
- package/src/sync/polling/fetchers/splitChangesFetcher.ts +5 -5
- package/src/sync/polling/types.ts +22 -1
- package/src/sync/polling/updaters/definitionChangesUpdater.ts +26 -20
- package/src/sync/streaming/SSEClient/index.ts +1 -1
- package/src/sync/streaming/SSEClient/types.ts +1 -1
- package/src/sync/streaming/UpdateWorkers/DefinitionsUpdateWorker.ts +15 -11
- package/src/sync/streaming/UpdateWorkers/types.ts +6 -0
- package/src/sync/streaming/parseUtils.ts +3 -4
- package/src/sync/streaming/pushManager.ts +4 -3
- package/cjs/storages/AbstractSplitsCacheAsync.js +0 -51
- package/cjs/storages/AbstractSplitsCacheSync.js +0 -76
- package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +0 -194
- package/cjs/storages/inMemory/SplitsCacheInMemory.js +0 -121
- package/cjs/storages/pluggable/SplitsCachePluggable.js +0 -212
- package/cjs/sync/polling/syncTasks/splitsSyncTask.js +0 -13
- package/cjs/sync/polling/updaters/splitChangesUpdater.js +0 -200
- package/cjs/sync/streaming/AuthClient/types.js +0 -2
- package/cjs/utils/inputValidation/splits.js +0 -25
- package/esm/storages/AbstractSplitsCacheAsync.js +0 -48
- package/esm/storages/AbstractSplitsCacheSync.js +0 -71
- package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +0 -191
- package/esm/storages/inMemory/SplitsCacheInMemory.js +0 -118
- package/esm/storages/pluggable/SplitsCachePluggable.js +0 -209
- package/esm/sync/polling/syncTasks/splitsSyncTask.js +0 -9
- package/esm/sync/polling/updaters/splitChangesUpdater.js +0 -194
- package/esm/sync/streaming/AuthClient/types.js +0 -1
- package/esm/utils/inputValidation/splitExistence.js +0 -15
- package/esm/utils/inputValidation/splits.js +0 -21
- package/src/sync/streaming/AuthClient/types.ts +0 -19
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SDK_SEGMENTS_ARRIVED, SEGMENTS_UPDATE } from '../../../readiness/constants';
|
|
2
|
-
import { LOG_PREFIX_INSTANTIATION,
|
|
2
|
+
import { LOG_PREFIX_INSTANTIATION, LOG_PREFIX_SYNC } from '../../../logger/constants';
|
|
3
3
|
import { timeout } from '../../../utils/promise/timeout';
|
|
4
4
|
/**
|
|
5
5
|
* Factory of SegmentChanges updater, a task that:
|
|
@@ -20,7 +20,7 @@ export function segmentChangesUpdaterFactory(log, segmentChangesFetcher, segment
|
|
|
20
20
|
return promise;
|
|
21
21
|
}
|
|
22
22
|
function updateSegment(segmentName, noCache, till, fetchOnlyNew, retries) {
|
|
23
|
-
log.debug("".concat(
|
|
23
|
+
log.debug("".concat(LOG_PREFIX_SYNC, "Processing segment ").concat(segmentName));
|
|
24
24
|
var sincePromise = Promise.resolve(segments.getChangeNumber(segmentName));
|
|
25
25
|
return sincePromise.then(function (since) {
|
|
26
26
|
// if fetchOnlyNew flag, avoid processing already fetched segments
|
|
@@ -28,14 +28,14 @@ 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(
|
|
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; });
|
|
35
35
|
});
|
|
36
36
|
}).catch(function (error) {
|
|
37
37
|
if (retries) {
|
|
38
|
-
log.warn("".concat(
|
|
38
|
+
log.warn("".concat(LOG_PREFIX_SYNC, "Retrying fetch of segment ").concat(segmentName, " (attempt #").concat(retries, "). Reason: ").concat(error));
|
|
39
39
|
return updateSegment(segmentName, noCache, till, fetchOnlyNew, retries - 1);
|
|
40
40
|
}
|
|
41
41
|
throw error;
|
|
@@ -54,7 +54,7 @@ export function segmentChangesUpdaterFactory(log, segmentChangesFetcher, segment
|
|
|
54
54
|
* @param till - till target for the provided segmentName, for CDN bypass.
|
|
55
55
|
*/
|
|
56
56
|
return function segmentChangesUpdater(fetchOnlyNew, segmentName, noCache, till) {
|
|
57
|
-
log.debug("".concat(
|
|
57
|
+
log.debug("".concat(LOG_PREFIX_SYNC, "Started segments update"));
|
|
58
58
|
// If not a segment name provided, read list of available segments names to be updated.
|
|
59
59
|
var segmentsPromise = Promise.resolve(segmentName ? [segmentName] : segments.getRegisteredSegments());
|
|
60
60
|
return segmentsPromise.then(function (segmentNames) {
|
|
@@ -63,7 +63,7 @@ export function segmentChangesUpdaterFactory(log, segmentChangesFetcher, segment
|
|
|
63
63
|
// if at least one segment fetch succeeded, mark segments ready
|
|
64
64
|
if (shouldUpdateFlags.some(function (update) { return update; }) || readyOnAlreadyExistentState) {
|
|
65
65
|
readyOnAlreadyExistentState = false;
|
|
66
|
-
if (readiness) {
|
|
66
|
+
if (readiness && !fetchOnlyNew) {
|
|
67
67
|
var metadata = {
|
|
68
68
|
type: SEGMENTS_UPDATE,
|
|
69
69
|
names: []
|
|
@@ -84,7 +84,7 @@ export function segmentChangesUpdaterFactory(log, segmentChangesFetcher, segment
|
|
|
84
84
|
log.error("".concat(LOG_PREFIX_INSTANTIATION, ": you passed a client-side type authorizationKey, please grab an SDK Key from Harness FME UI that is of type server-side."));
|
|
85
85
|
}
|
|
86
86
|
else {
|
|
87
|
-
log.warn("".concat(
|
|
87
|
+
log.warn("".concat(LOG_PREFIX_SYNC, "Error while doing fetch of segments. ").concat(error));
|
|
88
88
|
}
|
|
89
89
|
return false;
|
|
90
90
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CONNECTION_ESTABLISHED, DISABLED, ENABLED, OCCUPANCY_PRI, OCCUPANCY_SEC, PAUSED, STREAMING_STATUS } from '../../../utils/constants';
|
|
2
|
-
import { ControlType, PUSH_SUBSYSTEM_UP,
|
|
2
|
+
import { ControlType, PUSH_SUBSYSTEM_UP, PUSH_NON_RETRYABLE_ERROR, PUSH_SUBSYSTEM_DOWN } from '../constants';
|
|
3
3
|
var CONTROL_CHANNEL_REGEXS = [/control_pri$/, /control_sec$/];
|
|
4
4
|
var STREAMING_EVENT_TYPES = [OCCUPANCY_PRI, OCCUPANCY_SEC];
|
|
5
5
|
/**
|
|
@@ -70,7 +70,7 @@ export function notificationKeeperFactory(pushEmitter, telemetryTracker) {
|
|
|
70
70
|
c.cTime = timestamp;
|
|
71
71
|
if (controlType === ControlType.STREAMING_DISABLED) {
|
|
72
72
|
telemetryTracker.streamingEvent(STREAMING_STATUS, DISABLED);
|
|
73
|
-
pushEmitter.emit(
|
|
73
|
+
pushEmitter.emit(PUSH_NON_RETRYABLE_ERROR);
|
|
74
74
|
}
|
|
75
75
|
else if (hasPublishers) {
|
|
76
76
|
if (controlType === ControlType.STREAMING_PAUSED && hasResumed) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { errorParser, messageParser } from './NotificationParser';
|
|
2
2
|
import { notificationKeeperFactory } from './NotificationKeeper';
|
|
3
|
-
import { PUSH_RETRYABLE_ERROR,
|
|
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
|
/**
|
|
@@ -48,7 +48,7 @@ export function SSEHandlerFactory(log, pushEmitter, telemetryTracker) {
|
|
|
48
48
|
pushEmitter.emit(PUSH_RETRYABLE_ERROR);
|
|
49
49
|
}
|
|
50
50
|
else {
|
|
51
|
-
pushEmitter.emit(
|
|
51
|
+
pushEmitter.emit(PUSH_NON_RETRYABLE_ERROR);
|
|
52
52
|
}
|
|
53
53
|
},
|
|
54
54
|
/* NotificationProcessor */
|
|
@@ -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:
|
package/esm/sync/streaming/UpdateWorkers/{SplitsUpdateWorker.js → DefinitionsUpdateWorker.js}
RENAMED
|
@@ -1,40 +1,39 @@
|
|
|
1
1
|
import { STREAMING_PARSING_SPLIT_UPDATE } from '../../../logger/constants';
|
|
2
|
-
import {
|
|
2
|
+
import { SDK_DEFINITIONS_ARRIVED } from '../../../readiness/constants';
|
|
3
3
|
import { Backoff } from '../../../utils/Backoff';
|
|
4
4
|
import { SPLITS } from '../../../utils/constants';
|
|
5
5
|
import { RB_SEGMENT_UPDATE } from '../constants';
|
|
6
|
-
import {
|
|
6
|
+
import { parseUpdatePayload } from '../parseUtils';
|
|
7
7
|
import { FETCH_BACKOFF_BASE, FETCH_BACKOFF_MAX_WAIT, FETCH_BACKOFF_MAX_RETRIES } from './constants';
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
9
|
+
* DefinitionsUpdateWorker factory for Flags SDKs, where notifications pcn and changeNumber are environment-scoped
|
|
10
10
|
*/
|
|
11
|
-
export function
|
|
12
|
-
var
|
|
13
|
-
var
|
|
14
|
-
|
|
11
|
+
export function DefinitionsUpdateWorker(params, pollingManager) {
|
|
12
|
+
var log = params.settings.log, storage = params.storage, telemetryTracker = params.telemetryTracker, definitionsEventEmitter = params.readiness.definitions;
|
|
13
|
+
var definitionsSyncTask = pollingManager.definitionsSyncTask;
|
|
14
|
+
var ff = DefinitionsUpdateWorker(storage.definitions);
|
|
15
|
+
var rbs = DefinitionsUpdateWorker(storage.rbSegments);
|
|
16
|
+
function DefinitionsUpdateWorker(cache) {
|
|
15
17
|
var maxChangeNumber = -1;
|
|
16
18
|
var handleNewEvent = false;
|
|
17
19
|
var isHandlingEvent;
|
|
18
20
|
var cdnBypass;
|
|
19
21
|
var instantUpdate;
|
|
20
|
-
var backoff = new Backoff(
|
|
21
|
-
function
|
|
22
|
+
var backoff = new Backoff(__handleDefinitionUpdateCall, FETCH_BACKOFF_BASE, FETCH_BACKOFF_MAX_WAIT);
|
|
23
|
+
function __handleDefinitionUpdateCall() {
|
|
22
24
|
isHandlingEvent = true;
|
|
23
25
|
if (maxChangeNumber > cache.getChangeNumber()) {
|
|
24
26
|
handleNewEvent = false;
|
|
25
27
|
// fetch splits revalidating data if cached
|
|
26
|
-
|
|
28
|
+
definitionsSyncTask.execute(true, cdnBypass ? maxChangeNumber : undefined, instantUpdate).then(function () {
|
|
27
29
|
if (!isHandlingEvent)
|
|
28
30
|
return; // halt if `stop` has been called
|
|
29
31
|
if (handleNewEvent) {
|
|
30
|
-
|
|
32
|
+
__handleDefinitionUpdateCall();
|
|
31
33
|
}
|
|
32
34
|
else {
|
|
33
35
|
if (instantUpdate)
|
|
34
36
|
telemetryTracker.trackUpdatesFromSSE(SPLITS);
|
|
35
|
-
// fetch new registered segments for server-side API. Not retrying on error
|
|
36
|
-
if (segmentsSyncTask)
|
|
37
|
-
segmentsSyncTask.execute(true);
|
|
38
37
|
var attempts = backoff.attempts + 1;
|
|
39
38
|
if (ff.isSync() && rbs.isSync()) {
|
|
40
39
|
log.debug("Refresh completed".concat(cdnBypass ? ' bypassing the CDN' : '', " in ").concat(attempts, " attempts."));
|
|
@@ -52,7 +51,7 @@ export function SplitsUpdateWorker(log, storage, splitsSyncTask, splitsEventEmit
|
|
|
52
51
|
else {
|
|
53
52
|
backoff.reset();
|
|
54
53
|
cdnBypass = true;
|
|
55
|
-
|
|
54
|
+
__handleDefinitionUpdateCall();
|
|
56
55
|
}
|
|
57
56
|
}
|
|
58
57
|
});
|
|
@@ -80,7 +79,7 @@ export function SplitsUpdateWorker(log, storage, splitsSyncTask, splitsEventEmit
|
|
|
80
79
|
instantUpdate = { payload: payload, changeNumber: changeNumber, type: type };
|
|
81
80
|
}
|
|
82
81
|
if (backoff.timeoutID || !isHandlingEvent)
|
|
83
|
-
|
|
82
|
+
__handleDefinitionUpdateCall();
|
|
84
83
|
backoff.reset();
|
|
85
84
|
},
|
|
86
85
|
stop: function () {
|
|
@@ -96,7 +95,7 @@ export function SplitsUpdateWorker(log, storage, splitsSyncTask, splitsEventEmit
|
|
|
96
95
|
put: function (parsedData) {
|
|
97
96
|
if (parsedData.d && parsedData.c !== undefined) {
|
|
98
97
|
try {
|
|
99
|
-
var payload =
|
|
98
|
+
var payload = parseUpdatePayload(parsedData.c, parsedData.d);
|
|
100
99
|
if (payload) {
|
|
101
100
|
(parsedData.type === RB_SEGMENT_UPDATE ? rbs : ff).put(parsedData, payload);
|
|
102
101
|
return;
|
|
@@ -115,11 +114,11 @@ export function SplitsUpdateWorker(log, storage, splitsSyncTask, splitsEventEmit
|
|
|
115
114
|
* @param splitName - name of split to kill
|
|
116
115
|
* @param defaultTreatment - default treatment value
|
|
117
116
|
*/
|
|
118
|
-
|
|
117
|
+
killDefinition: function (_a) {
|
|
119
118
|
var changeNumber = _a.changeNumber, splitName = _a.splitName, defaultTreatment = _a.defaultTreatment;
|
|
120
|
-
if (storage.
|
|
119
|
+
if (storage.definitions.killLocally(splitName, defaultTreatment, changeNumber)) {
|
|
121
120
|
// trigger an SDK_UPDATE if Split was killed locally
|
|
122
|
-
|
|
121
|
+
definitionsEventEmitter.emit(SDK_DEFINITIONS_ARRIVED, true);
|
|
123
122
|
}
|
|
124
123
|
// queues the SplitChanges fetch (only if changeNumber is newer)
|
|
125
124
|
ff.put({ changeNumber: changeNumber });
|
|
@@ -5,7 +5,7 @@ export var SECONDS_BEFORE_EXPIRATION = 600;
|
|
|
5
5
|
* emitted on SSE and Authenticate non-recoverable errors, STREAMING_DISABLED control notification and authentication with pushEnabled false
|
|
6
6
|
* triggers `handleNonRetryableError` call
|
|
7
7
|
*/
|
|
8
|
-
export var
|
|
8
|
+
export var PUSH_NON_RETRYABLE_ERROR = 'PUSH_NON_RETRYABLE_ERROR';
|
|
9
9
|
/**
|
|
10
10
|
* emitted on SSE and Authenticate recoverable errors
|
|
11
11
|
* triggers `handleRetryableError` call
|
|
@@ -17,7 +17,7 @@ export var PUSH_RETRYABLE_ERROR = 'PUSH_RETRYABLE_ERROR';
|
|
|
17
17
|
*/
|
|
18
18
|
export var PUSH_SUBSYSTEM_UP = 'PUSH_SUBSYSTEM_UP';
|
|
19
19
|
/**
|
|
20
|
-
* emitted on STREAMING_PAUSED control notification, OCCUPANCY equal to 0,
|
|
20
|
+
* emitted on STREAMING_PAUSED control notification, OCCUPANCY equal to 0, PUSH_NON_RETRYABLE_ERROR and PUSH_RETRYABLE_ERROR events.
|
|
21
21
|
* triggers `startPolling` and `stopWorkers` calls
|
|
22
22
|
*/
|
|
23
23
|
export var PUSH_SUBSYSTEM_DOWN = 'PUSH_SUBSYSTEM_DOWN';
|
|
@@ -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';
|
|
@@ -30,22 +30,22 @@ function decompress(data, compression) {
|
|
|
30
30
|
throw new Error("Invalid compression algorithm #".concat(compression));
|
|
31
31
|
}
|
|
32
32
|
/**
|
|
33
|
-
* Decode, decompress and parse the provided 'data' into
|
|
33
|
+
* Decode, decompress and parse the provided 'data' into an object of type T
|
|
34
34
|
*
|
|
35
35
|
* @param data - base64 encoded string
|
|
36
36
|
* @param compression - 1 GZIP, 2 ZLIB
|
|
37
37
|
* @param avoidPrecisionLoss - true as default, set it as false if dont need to avoid precission loss
|
|
38
|
-
* @returns
|
|
38
|
+
* @returns parsed object
|
|
39
39
|
* @throws if data string cannot be decoded, decompressed or parsed
|
|
40
40
|
*/
|
|
41
|
-
export function
|
|
41
|
+
export function parseCompressedData(data, compression, avoidPrecisionLoss) {
|
|
42
42
|
if (avoidPrecisionLoss === void 0) { avoidPrecisionLoss = true; }
|
|
43
|
-
var
|
|
44
|
-
var
|
|
45
|
-
// replace numbers to strings, to avoid losing precision
|
|
43
|
+
var binData = decompress(data, compression);
|
|
44
|
+
var str = Uint8ArrayToString(binData);
|
|
45
|
+
// replace numbers to strings, to avoid losing precision (e.g., 64-bit IDs in KeyList)
|
|
46
46
|
if (avoidPrecisionLoss)
|
|
47
|
-
|
|
48
|
-
return JSON.parse(
|
|
47
|
+
str = str.replace(/\d+/g, '"$&"');
|
|
48
|
+
return JSON.parse(str);
|
|
49
49
|
}
|
|
50
50
|
/**
|
|
51
51
|
* Decode, decompress and parse the provided 'data' into a Bitmap object
|
|
@@ -73,11 +73,11 @@ export function isInBitmap(bitmap, hash64hex) {
|
|
|
73
73
|
return (bitmap[internal] & 1 << offset) > 0;
|
|
74
74
|
}
|
|
75
75
|
/**
|
|
76
|
-
* Parse
|
|
76
|
+
* Parse notifications for instant updates
|
|
77
77
|
*/
|
|
78
|
-
export function
|
|
78
|
+
export function parseUpdatePayload(compression, data) {
|
|
79
79
|
return compression > 0 ?
|
|
80
|
-
|
|
80
|
+
parseCompressedData(data, compression, false) :
|
|
81
81
|
JSON.parse(decodeFromBase64(data));
|
|
82
82
|
}
|
|
83
83
|
var DEFAULT_MAX_INTERVAL = 60000;
|
|
@@ -3,15 +3,14 @@ import { Backoff } from '../../utils/Backoff';
|
|
|
3
3
|
import { SSEHandlerFactory } from './SSEHandler';
|
|
4
4
|
import { MySegmentsUpdateWorker } from './UpdateWorkers/MySegmentsUpdateWorker';
|
|
5
5
|
import { SegmentsUpdateWorker } from './UpdateWorkers/SegmentsUpdateWorker';
|
|
6
|
-
import {
|
|
7
|
-
import { authenticateFactory, hashUserKey } from './AuthClient';
|
|
6
|
+
import { DefinitionsUpdateWorker } from './UpdateWorkers/DefinitionsUpdateWorker';
|
|
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,
|
|
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
|
-
import { getDelay, isInBitmap, parseBitmap,
|
|
13
|
+
import { getDelay, isInBitmap, parseBitmap, parseCompressedData } from './parseUtils';
|
|
15
14
|
import { hash64 } from '../../utils/murmur3/murmur3_64';
|
|
16
15
|
import { TOKEN_REFRESH, AUTH_REJECTION } from '../../utils/constants';
|
|
17
16
|
/**
|
|
@@ -19,8 +18,9 @@ import { TOKEN_REFRESH, AUTH_REJECTION } from '../../utils/constants';
|
|
|
19
18
|
* - for server-side if key is not provided in settings.
|
|
20
19
|
* - for client-side, with support for multiple clients, if key is provided in settings
|
|
21
20
|
*/
|
|
22
|
-
export function pushManagerFactory(params, pollingManager) {
|
|
23
|
-
|
|
21
|
+
export function pushManagerFactory(params, pollingManager, definitionsUpdateWorkerFactory) {
|
|
22
|
+
if (definitionsUpdateWorkerFactory === void 0) { definitionsUpdateWorkerFactory = DefinitionsUpdateWorker; }
|
|
23
|
+
var settings = params.settings, storage = params.storage, serviceApi = params.serviceApi, platform = params.platform, telemetryTracker = params.telemetryTracker;
|
|
24
24
|
// `userKey` is the matching key of main client in client-side SDK.
|
|
25
25
|
// It can be used to check if running on client-side or server-side SDK.
|
|
26
26
|
var userKey = checkIfServerSide(settings) ? undefined : getMatching(settings.core.key);
|
|
@@ -34,7 +34,6 @@ export function pushManagerFactory(params, pollingManager) {
|
|
|
34
34
|
log.warn(STREAMING_FALLBACK, [e]);
|
|
35
35
|
return;
|
|
36
36
|
}
|
|
37
|
-
var authenticate = authenticateFactory(splitApi.fetchAuth);
|
|
38
37
|
// init feedback loop
|
|
39
38
|
var pushEmitter = new platform.EventEmitter();
|
|
40
39
|
var sseHandler = SSEHandlerFactory(log, pushEmitter, telemetryTracker);
|
|
@@ -42,19 +41,17 @@ export function pushManagerFactory(params, pollingManager) {
|
|
|
42
41
|
// init workers
|
|
43
42
|
// MySegmentsUpdateWorker (client-side) are initiated in `add` method
|
|
44
43
|
var segmentsUpdateWorker = userKey ? undefined : SegmentsUpdateWorker(log, pollingManager.segmentsSyncTask, storage.segments);
|
|
45
|
-
// For server-side we pass the segmentsSyncTask, used by
|
|
46
|
-
var
|
|
47
|
-
// [Only for client-side] map of hashes to user keys, to dispatch membership update events to the corresponding MySegmentsUpdateWorker
|
|
48
|
-
var userKeyHashes = {};
|
|
44
|
+
// For server-side we pass the segmentsSyncTask, used by DefinitionsUpdateWorker to fetch new segments
|
|
45
|
+
var definitionsUpdateWorker = definitionsUpdateWorkerFactory(params, pollingManager);
|
|
49
46
|
// [Only for client-side] map of user keys to their corresponding hash64 and MySegmentsUpdateWorkers.
|
|
50
47
|
// Hash64 is used to process membership update events and dispatch actions to the corresponding MySegmentsUpdateWorker.
|
|
51
48
|
var clients = {};
|
|
52
49
|
// [Only for client-side] variable to flag that a new client was added. It is needed to reconnect streaming.
|
|
53
50
|
var connectForNewClient = false;
|
|
54
|
-
// flag that indicates if `stop/disconnectPush` was called, either by the SyncManager, when the client is destroyed, or due to a
|
|
51
|
+
// flag that indicates if `stop/disconnectPush` was called, either by the SyncManager, when the client is destroyed, or due to a PUSH_NON_RETRYABLE_ERROR error.
|
|
55
52
|
// It is used to halt the `connectPush` process if it was in progress.
|
|
56
53
|
var disconnected;
|
|
57
|
-
// flag that indicates a
|
|
54
|
+
// flag that indicates a PUSH_NON_RETRYABLE_ERROR, condition with which starting pushManager again is ignored.
|
|
58
55
|
// true if STREAMING_DISABLED control event, or 'pushEnabled: false', or non-recoverable SSE or Auth errors.
|
|
59
56
|
var disabled; // `disabled` implies `disconnected === true`
|
|
60
57
|
/** PushManager functions related to initialization */
|
|
@@ -90,14 +87,14 @@ export function pushManagerFactory(params, pollingManager) {
|
|
|
90
87
|
log.info(STREAMING_CONNECTING);
|
|
91
88
|
disconnected = false;
|
|
92
89
|
var userKeys = userKey ? Object.keys(clients) : undefined;
|
|
93
|
-
|
|
90
|
+
serviceApi.fetchAuth(userKeys).then(function (authData) {
|
|
94
91
|
if (disconnected)
|
|
95
92
|
return;
|
|
96
|
-
// 'pushEnabled: false' is handled as a
|
|
93
|
+
// 'pushEnabled: false' is handled as a PUSH_NON_RETRYABLE_ERROR instead of PUSH_SUBSYSTEM_DOWN, in order to
|
|
97
94
|
// close the sseClient in case the org has been bloqued while the instance was connected to streaming
|
|
98
95
|
if (!authData.pushEnabled) {
|
|
99
96
|
log.info(STREAMING_DISABLED);
|
|
100
|
-
pushEmitter.emit(
|
|
97
|
+
pushEmitter.emit(PUSH_NON_RETRYABLE_ERROR);
|
|
101
98
|
return;
|
|
102
99
|
}
|
|
103
100
|
// [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
|
|
@@ -112,7 +109,7 @@ export function pushManagerFactory(params, pollingManager) {
|
|
|
112
109
|
// Handle 4XX HTTP errors: 401 (invalid SDK Key) or 400 (using incorrect SDK Key, i.e., client-side SDK Key on server-side)
|
|
113
110
|
if (error.statusCode >= 400 && error.statusCode < 500) {
|
|
114
111
|
telemetryTracker.streamingEvent(AUTH_REJECTION);
|
|
115
|
-
pushEmitter.emit(
|
|
112
|
+
pushEmitter.emit(PUSH_NON_RETRYABLE_ERROR);
|
|
116
113
|
return;
|
|
117
114
|
}
|
|
118
115
|
// Handle other HTTP and network errors as recoverable errors
|
|
@@ -136,7 +133,7 @@ export function pushManagerFactory(params, pollingManager) {
|
|
|
136
133
|
}
|
|
137
134
|
// cancel scheduled fetch retries of Splits, Segments, and MySegments Update Workers
|
|
138
135
|
function stopWorkers() {
|
|
139
|
-
|
|
136
|
+
definitionsUpdateWorker.stop();
|
|
140
137
|
if (userKey)
|
|
141
138
|
forOwn(clients, function (_a) {
|
|
142
139
|
var worker = _a.worker;
|
|
@@ -152,7 +149,7 @@ export function pushManagerFactory(params, pollingManager) {
|
|
|
152
149
|
connectPushRetryBackoff.reset();
|
|
153
150
|
});
|
|
154
151
|
/** Fallback to polling without retry due to: STREAMING_DISABLED control event, or 'pushEnabled: false', or non-recoverable SSE and Authentication errors */
|
|
155
|
-
pushEmitter.on(
|
|
152
|
+
pushEmitter.on(PUSH_NON_RETRYABLE_ERROR, function handleNonRetryableError() {
|
|
156
153
|
disabled = true;
|
|
157
154
|
// Note: `stopWorkers` is been called twice, but it is not harmful
|
|
158
155
|
disconnectPush();
|
|
@@ -178,9 +175,12 @@ export function pushManagerFactory(params, pollingManager) {
|
|
|
178
175
|
connectPush();
|
|
179
176
|
});
|
|
180
177
|
/** Functions related to synchronization (Queues and Workers in the spec) */
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
pushEmitter.on(
|
|
178
|
+
// Some notification types are specific to the Feature flags or Configs SDKs. Their handlers are
|
|
179
|
+
// registered unconditionally, since the SDK only subscribes to the channels of its own entities.
|
|
180
|
+
pushEmitter.on(SPLIT_KILL, definitionsUpdateWorker.killDefinition);
|
|
181
|
+
pushEmitter.on(SPLIT_UPDATE, definitionsUpdateWorker.put);
|
|
182
|
+
pushEmitter.on(CONFIG_UPDATE, definitionsUpdateWorker.put);
|
|
183
|
+
pushEmitter.on(RB_SEGMENT_UPDATE, definitionsUpdateWorker.put);
|
|
184
184
|
function handleMySegmentsUpdate(parsedData) {
|
|
185
185
|
switch (parsedData.u) {
|
|
186
186
|
case UpdateStrategy.BoundedFetchRequest: {
|
|
@@ -203,7 +203,7 @@ export function pushManagerFactory(params, pollingManager) {
|
|
|
203
203
|
case UpdateStrategy.KeyList: {
|
|
204
204
|
var keyList = void 0, added_1, removed_1;
|
|
205
205
|
try {
|
|
206
|
-
keyList =
|
|
206
|
+
keyList = parseCompressedData(parsedData.d, parsedData.c);
|
|
207
207
|
added_1 = new Set(keyList.a);
|
|
208
208
|
removed_1 = new Set(keyList.r);
|
|
209
209
|
}
|
|
@@ -282,9 +282,7 @@ export function pushManagerFactory(params, pollingManager) {
|
|
|
282
282
|
},
|
|
283
283
|
// [Only for client-side]
|
|
284
284
|
add: function (userKey, mySegmentsSyncTask) {
|
|
285
|
-
|
|
286
|
-
if (!userKeyHashes[hash]) {
|
|
287
|
-
userKeyHashes[hash] = userKey;
|
|
285
|
+
if (!clients[userKey]) {
|
|
288
286
|
clients[userKey] = {
|
|
289
287
|
hash64: hash64(userKey),
|
|
290
288
|
worker: MySegmentsUpdateWorker(log, storage, mySegmentsSyncTask, telemetryTracker)
|
|
@@ -305,8 +303,6 @@ export function pushManagerFactory(params, pollingManager) {
|
|
|
305
303
|
},
|
|
306
304
|
// [Only for client-side]
|
|
307
305
|
remove: function (userKey) {
|
|
308
|
-
var hash = hashUserKey(userKey);
|
|
309
|
-
delete userKeyHashes[hash];
|
|
310
306
|
delete clients[userKey];
|
|
311
307
|
}
|
|
312
308
|
});
|
|
@@ -4,7 +4,7 @@ import { SUBMITTERS_PUSH_FULL_QUEUE } from '../../logger/constants';
|
|
|
4
4
|
* Submitter that periodically posts tracked events
|
|
5
5
|
*/
|
|
6
6
|
export function eventsSubmitterFactory(params) {
|
|
7
|
-
var _a = params.settings, log = _a.log, eventsPushRate = _a.scheduler.eventsPushRate, eventsFirstPushWindow = _a.startup.eventsFirstPushWindow, postEventsBulk = params.
|
|
7
|
+
var _a = params.settings, log = _a.log, eventsPushRate = _a.scheduler.eventsPushRate, eventsFirstPushWindow = _a.startup.eventsFirstPushWindow, postEventsBulk = params.serviceApi.postEventsBulk, events = params.storage.events;
|
|
8
8
|
// don't retry events.
|
|
9
9
|
var submitter = submitterFactory(log, postEventsBulk, events, eventsPushRate);
|
|
10
10
|
// Set a timer for the first push window of events.
|
|
@@ -25,7 +25,7 @@ var IMPRESSIONS_COUNT_RATE = 1800000; // 30 minutes
|
|
|
25
25
|
* Submitter that periodically posts impression counts
|
|
26
26
|
*/
|
|
27
27
|
export function impressionCountsSubmitterFactory(params) {
|
|
28
|
-
var log = params.settings.log, postTestImpressionsCount = params.
|
|
28
|
+
var log = params.settings.log, postTestImpressionsCount = params.serviceApi.postTestImpressionsCount, impressionCounts = params.storage.impressionCounts;
|
|
29
29
|
// retry impressions counts only once.
|
|
30
30
|
return submitterFactory(log, postTestImpressionsCount, impressionCounts, IMPRESSIONS_COUNT_RATE, fromImpressionCountsCollector, 1);
|
|
31
31
|
}
|
|
@@ -11,7 +11,7 @@ export function fromImpressionsCollector(sendLabels, data) {
|
|
|
11
11
|
dto.push({
|
|
12
12
|
f: name,
|
|
13
13
|
i: value.map(function (entry) {
|
|
14
|
-
|
|
14
|
+
return {
|
|
15
15
|
k: entry.keyName,
|
|
16
16
|
t: entry.treatment,
|
|
17
17
|
m: entry.time,
|
|
@@ -19,9 +19,10 @@ export function fromImpressionsCollector(sendLabels, data) {
|
|
|
19
19
|
r: sendLabels ? entry.label : undefined,
|
|
20
20
|
b: entry.bucketingKey,
|
|
21
21
|
pt: entry.pt,
|
|
22
|
-
properties: entry.properties
|
|
22
|
+
properties: entry.properties,
|
|
23
|
+
// @TODO: add entityType to public SplitIO.ImpressionDTO type
|
|
24
|
+
et: entry.entityType, // Definition type
|
|
23
25
|
};
|
|
24
|
-
return keyImpression;
|
|
25
26
|
})
|
|
26
27
|
});
|
|
27
28
|
});
|
|
@@ -31,7 +32,7 @@ export function fromImpressionsCollector(sendLabels, data) {
|
|
|
31
32
|
* Submitter that periodically posts impressions data
|
|
32
33
|
*/
|
|
33
34
|
export function impressionsSubmitterFactory(params) {
|
|
34
|
-
var _a = params.settings, log = _a.log, impressionsRefreshRate = _a.scheduler.impressionsRefreshRate, labelsEnabled = _a.core.labelsEnabled, postTestImpressionsBulk = params.
|
|
35
|
+
var _a = params.settings, log = _a.log, impressionsRefreshRate = _a.scheduler.impressionsRefreshRate, labelsEnabled = _a.core.labelsEnabled, postTestImpressionsBulk = params.serviceApi.postTestImpressionsBulk, impressions = params.storage.impressions;
|
|
35
36
|
// retry impressions only once.
|
|
36
37
|
var syncTask = submitterFactory(log, postTestImpressionsBulk, impressions, impressionsRefreshRate, fromImpressionsCollector.bind(undefined, labelsEnabled), 1);
|
|
37
38
|
// register impressions submitter to be executed when impressions cache is full
|
|
@@ -102,18 +102,17 @@ export function telemetrySubmitterFactory(params) {
|
|
|
102
102
|
var telemetry = params.storage.telemetry, now = params.platform.now;
|
|
103
103
|
if (!telemetry || !now)
|
|
104
104
|
return; // No submitter created if telemetry cache is not defined
|
|
105
|
-
var settings = params.settings, _a = params.settings, log = _a.log, telemetryRefreshRate = _a.scheduler.telemetryRefreshRate,
|
|
105
|
+
var settings = params.settings, _a = params.settings, log = _a.log, telemetryRefreshRate = _a.scheduler.telemetryRefreshRate, serviceApi = params.serviceApi, readiness = params.readiness;
|
|
106
106
|
var stopTimer = timer(now);
|
|
107
|
-
var submitter = firstPushWindowDecorator(submitterFactory(log,
|
|
107
|
+
var submitter = firstPushWindowDecorator(submitterFactory(log, serviceApi.postMetricsUsage, telemetry, telemetryRefreshRate, undefined, 0, true), telemetryRefreshRate);
|
|
108
108
|
readiness.gate.once(SDK_READY_FROM_CACHE, function () {
|
|
109
109
|
telemetry.recordTimeUntilReadyFromCache(stopTimer());
|
|
110
110
|
});
|
|
111
|
-
sdkReadinessManager.incInternalReadyCbCount();
|
|
112
111
|
readiness.gate.once(SDK_READY, function () {
|
|
113
112
|
telemetry.recordTimeUntilReady(stopTimer());
|
|
114
113
|
// Post config data when the SDK is ready and if the telemetry submitter was started
|
|
115
114
|
if (submitter.isRunning()) {
|
|
116
|
-
var postMetricsConfigTask = submitterFactory(log,
|
|
115
|
+
var postMetricsConfigTask = submitterFactory(log, serviceApi.postMetricsConfig, telemetryCacheConfigAdapter(telemetry, settings), 0, undefined, 0, true);
|
|
117
116
|
postMetricsConfigTask.execute();
|
|
118
117
|
}
|
|
119
118
|
});
|
|
@@ -5,7 +5,7 @@ var UNIQUE_KEYS_RATE = 900000; // 15 minutes
|
|
|
5
5
|
* Submitter that periodically posts impression counts
|
|
6
6
|
*/
|
|
7
7
|
export function uniqueKeysSubmitterFactory(params) {
|
|
8
|
-
var _a = params.settings, log = _a.log, key = _a.core.key, _b = params.
|
|
8
|
+
var _a = params.settings, log = _a.log, key = _a.core.key, _b = params.serviceApi, postUniqueKeysBulkCs = _b.postUniqueKeysBulkCs, postUniqueKeysBulkSs = _b.postUniqueKeysBulkSs, uniqueKeys = params.storage.uniqueKeys;
|
|
9
9
|
var isClientSide = key !== undefined;
|
|
10
10
|
var postUniqueKeysBulk = isClientSide ? postUniqueKeysBulkCs : postUniqueKeysBulkSs;
|
|
11
11
|
var syncTask = submitterFactory(log, postUniqueKeysBulk, uniqueKeys, UNIQUE_KEYS_RATE);
|
|
@@ -3,8 +3,8 @@ import { PUSH_SUBSYSTEM_UP, PUSH_SUBSYSTEM_DOWN } from './streaming/constants';
|
|
|
3
3
|
import { SYNC_START_POLLING, SYNC_CONTINUE_POLLING, SYNC_STOP_POLLING } from '../logger/constants';
|
|
4
4
|
import { isConsentGranted } from '../consent';
|
|
5
5
|
import { POLLING, STREAMING, SYNC_MODE_UPDATE } from '../utils/constants';
|
|
6
|
-
import {
|
|
7
|
-
import { usesSegmentsSync } from '../storages/
|
|
6
|
+
import { SDK_DEFINITIONS_CACHE_LOADED } from '../readiness/constants';
|
|
7
|
+
import { usesSegmentsSync } from '../storages/AbstractDefinitionsCacheSync';
|
|
8
8
|
/**
|
|
9
9
|
* Online SyncManager factory.
|
|
10
10
|
* Can be used for server-side API, and client-side API with or without multiple clients.
|
|
@@ -26,7 +26,7 @@ export function syncManagerOnlineFactory(pollingManagerFactory, pushManagerFacto
|
|
|
26
26
|
pushManagerFactory(params, pollingManager) :
|
|
27
27
|
undefined;
|
|
28
28
|
/** Submitter Manager */
|
|
29
|
-
// It is not
|
|
29
|
+
// It is not injected as push and polling managers, because at the moment it is required
|
|
30
30
|
var submitterManager = submitterManagerFactory(params);
|
|
31
31
|
/** Sync Manager logic */
|
|
32
32
|
function startPolling() {
|
|
@@ -74,7 +74,7 @@ export function syncManagerOnlineFactory(pollingManagerFactory, pushManagerFacto
|
|
|
74
74
|
if (startFirstTime) {
|
|
75
75
|
// Emits SDK_READY_FROM_CACHE
|
|
76
76
|
if (!cacheMetadata.initialCacheLoad) {
|
|
77
|
-
readiness.
|
|
77
|
+
readiness.definitions.emit(SDK_DEFINITIONS_CACHE_LOADED, cacheMetadata);
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
80
|
// start syncing splits and segments
|
package/esm/utils/Backoff.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
var Backoff = /** @class */ (function () {
|
|
2
2
|
/**
|
|
3
|
-
* Schedule function calls with exponential backoff
|
|
3
|
+
* Schedule function calls with exponential backoff.
|
|
4
|
+
* @param cb - The function to call. Must return a promise if used with `scheduleCallAsync`.
|
|
4
5
|
*/
|
|
5
6
|
function Backoff(cb, baseMillis, maxMillis) {
|
|
6
7
|
this.baseMillis = Backoff.__TEST__BASE_MILLIS || baseMillis || Backoff.DEFAULT_BASE_MILLIS;
|
|
@@ -17,19 +18,50 @@ var Backoff = /** @class */ (function () {
|
|
|
17
18
|
var delayInMillis = Math.min(this.baseMillis * Math.pow(2, this.attempts), this.maxMillis);
|
|
18
19
|
if (this.timeoutID)
|
|
19
20
|
clearTimeout(this.timeoutID);
|
|
21
|
+
this.attempts++;
|
|
20
22
|
this.timeoutID = setTimeout(function () {
|
|
21
23
|
_this.timeoutID = undefined;
|
|
22
24
|
_this.cb();
|
|
23
25
|
}, delayInMillis);
|
|
24
|
-
this.attempts++;
|
|
25
26
|
return delayInMillis;
|
|
26
27
|
};
|
|
27
|
-
|
|
28
|
+
/**
|
|
29
|
+
* Schedule a delayed call to `cb`
|
|
30
|
+
* @returns a promise that resolves/rejects with the result of the `cb` function, which must return a promise.
|
|
31
|
+
*/
|
|
32
|
+
Backoff.prototype.scheduleCallAsync = function () {
|
|
33
|
+
var _this = this;
|
|
34
|
+
var delayInMillis = Math.min(this.baseMillis * Math.pow(2, this.attempts), this.maxMillis);
|
|
35
|
+
if (this.timeoutID)
|
|
36
|
+
clearTimeout(this.timeoutID);
|
|
37
|
+
this.attempts++;
|
|
38
|
+
return new Promise(function (resolve, reject) {
|
|
39
|
+
_this.pending = { resolve: resolve, reject: reject };
|
|
40
|
+
_this.timeoutID = setTimeout(function () {
|
|
41
|
+
_this.timeoutID = undefined;
|
|
42
|
+
_this.pending = undefined;
|
|
43
|
+
_this.cb().then(resolve, reject);
|
|
44
|
+
}, delayInMillis);
|
|
45
|
+
});
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Reset the backoff attempts, canceling any scheduled `cb` call. If a `scheduleCallAsync` call is pending
|
|
49
|
+
* and the caller wants to settle it immediately instead of waiting for `cb` to be invoked, pass `settle`:
|
|
50
|
+
* `{ value }` to resolve, or `{ error }` to reject.
|
|
51
|
+
*/
|
|
52
|
+
Backoff.prototype.reset = function (settle) {
|
|
28
53
|
this.attempts = 0;
|
|
29
54
|
if (this.timeoutID) {
|
|
30
55
|
clearTimeout(this.timeoutID);
|
|
31
56
|
this.timeoutID = undefined;
|
|
32
57
|
}
|
|
58
|
+
if (settle && this.pending) {
|
|
59
|
+
if ('value' in settle)
|
|
60
|
+
this.pending.resolve(settle.value);
|
|
61
|
+
else
|
|
62
|
+
this.pending.reject(settle.error);
|
|
63
|
+
this.pending = undefined;
|
|
64
|
+
}
|
|
33
65
|
};
|
|
34
66
|
Backoff.DEFAULT_BASE_MILLIS = 1000; // 1 second
|
|
35
67
|
Backoff.DEFAULT_MAX_MILLIS = 1800000; // 30 minutes
|