@splitsoftware/splitio-commons 1.6.2-rc.7 → 1.6.2-rc.9
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 +2 -1
- package/cjs/consent/sdkUserConsent.js +2 -2
- package/cjs/evaluator/index.js +5 -5
- package/cjs/listeners/browser.js +1 -2
- package/cjs/logger/constants.js +1 -2
- package/cjs/sdkClient/client.js +19 -7
- package/cjs/sdkClient/sdkClient.js +1 -3
- package/cjs/sdkFactory/index.js +5 -26
- package/cjs/services/splitApi.js +4 -24
- package/cjs/storages/KeyBuilderSS.js +48 -15
- package/cjs/storages/inLocalStorage/index.js +1 -5
- package/cjs/storages/inMemory/ImpressionCountsCacheInMemory.js +1 -12
- package/cjs/storages/inMemory/InMemoryStorage.js +2 -6
- package/cjs/storages/inMemory/InMemoryStorageCS.js +2 -6
- package/cjs/storages/inMemory/TelemetryCacheInMemory.js +9 -6
- package/cjs/storages/inRedis/EventsCacheInRedis.js +1 -1
- package/cjs/storages/inRedis/TelemetryCacheInRedis.js +100 -0
- package/cjs/storages/inRedis/constants.js +1 -4
- package/cjs/storages/inRedis/index.js +1 -15
- package/cjs/storages/pluggable/TelemetryCachePluggable.js +126 -0
- package/cjs/storages/pluggable/index.js +19 -15
- package/cjs/sync/submitters/submitterManager.js +0 -3
- package/cjs/sync/submitters/telemetrySubmitter.js +7 -5
- package/cjs/trackers/impressionsTracker.js +41 -22
- package/cjs/utils/constants/index.js +2 -4
- package/cjs/utils/lang/maps.js +15 -7
- package/cjs/utils/settingsValidation/impressionsMode.js +2 -2
- package/cjs/utils/settingsValidation/index.js +0 -4
- package/esm/consent/sdkUserConsent.js +2 -2
- package/esm/evaluator/index.js +5 -5
- package/esm/listeners/browser.js +2 -3
- package/esm/logger/constants.js +0 -1
- package/esm/sdkClient/client.js +19 -7
- package/esm/sdkClient/sdkClient.js +1 -3
- package/esm/sdkFactory/index.js +5 -26
- package/esm/services/splitApi.js +4 -24
- package/esm/storages/KeyBuilderSS.js +44 -14
- package/esm/storages/inLocalStorage/index.js +2 -6
- package/esm/storages/inMemory/ImpressionCountsCacheInMemory.js +1 -12
- package/esm/storages/inMemory/InMemoryStorage.js +4 -8
- package/esm/storages/inMemory/InMemoryStorageCS.js +3 -7
- package/esm/storages/inMemory/TelemetryCacheInMemory.js +8 -6
- package/esm/storages/inRedis/EventsCacheInRedis.js +1 -1
- package/esm/storages/inRedis/TelemetryCacheInRedis.js +100 -0
- package/esm/storages/inRedis/constants.js +0 -3
- package/esm/storages/inRedis/index.js +2 -16
- package/esm/storages/pluggable/TelemetryCachePluggable.js +126 -0
- package/esm/storages/pluggable/index.js +19 -15
- package/esm/sync/submitters/submitterManager.js +0 -3
- package/esm/sync/submitters/telemetrySubmitter.js +8 -6
- package/esm/trackers/impressionsTracker.js +41 -22
- package/esm/utils/constants/index.js +0 -2
- package/esm/utils/lang/maps.js +15 -7
- package/esm/utils/settingsValidation/impressionsMode.js +3 -3
- package/esm/utils/settingsValidation/index.js +0 -4
- package/package.json +2 -1
- package/src/consent/sdkUserConsent.ts +2 -2
- package/src/evaluator/index.ts +6 -6
- package/src/listeners/browser.ts +2 -3
- package/src/logger/.DS_Store +0 -0
- package/src/logger/constants.ts +0 -1
- package/src/sdkClient/client.ts +21 -8
- package/src/sdkClient/sdkClient.ts +1 -3
- package/src/sdkFactory/index.ts +5 -29
- package/src/sdkFactory/types.ts +4 -7
- package/src/services/splitApi.ts +4 -26
- package/src/services/types.ts +2 -8
- package/src/storages/KeyBuilderSS.ts +53 -17
- package/src/storages/inLocalStorage/index.ts +2 -5
- package/src/storages/inMemory/ImpressionCountsCacheInMemory.ts +1 -16
- package/src/storages/inMemory/InMemoryStorage.ts +4 -7
- package/src/storages/inMemory/InMemoryStorageCS.ts +3 -7
- package/src/storages/inMemory/TelemetryCacheInMemory.ts +9 -7
- package/src/storages/inRedis/EventsCacheInRedis.ts +1 -1
- package/src/storages/inRedis/TelemetryCacheInRedis.ts +122 -2
- package/src/storages/inRedis/constants.ts +0 -3
- package/src/storages/inRedis/index.ts +3 -12
- package/src/storages/pluggable/TelemetryCachePluggable.ts +147 -2
- package/src/storages/pluggable/index.ts +20 -16
- package/src/storages/types.ts +13 -34
- package/src/sync/submitters/submitterManager.ts +0 -2
- package/src/sync/submitters/telemetrySubmitter.ts +14 -9
- package/src/sync/submitters/types.ts +40 -26
- package/src/trackers/impressionsTracker.ts +48 -27
- package/src/trackers/types.ts +0 -28
- package/src/types.ts +1 -5
- package/src/utils/constants/index.ts +0 -2
- package/src/utils/lang/maps.ts +20 -8
- package/src/utils/settingsValidation/impressionsMode.ts +3 -3
- package/src/utils/settingsValidation/index.ts +0 -5
- package/types/logger/constants.d.ts +0 -1
- package/types/sdkFactory/types.d.ts +2 -4
- package/types/services/types.d.ts +2 -6
- package/types/storages/KeyBuilderSS.d.ts +7 -4
- package/types/storages/inMemory/ImpressionCountsCacheInMemory.d.ts +1 -5
- package/types/storages/inMemory/TelemetryCacheInMemory.d.ts +6 -3
- package/types/storages/inRedis/EventsCacheInRedis.d.ts +1 -1
- package/types/storages/inRedis/TelemetryCacheInRedis.d.ts +16 -1
- package/types/storages/inRedis/constants.d.ts +0 -3
- package/types/storages/pluggable/TelemetryCachePluggable.d.ts +17 -1
- package/types/storages/types.d.ts +10 -21
- package/types/sync/submitters/telemetrySubmitter.d.ts +1 -1
- package/types/sync/submitters/types.d.ts +13 -24
- package/types/trackers/impressionsTracker.d.ts +6 -4
- package/types/trackers/types.d.ts +0 -23
- package/types/types.d.ts +1 -5
- package/types/utils/constants/index.d.ts +0 -2
- package/types/utils/lang/maps.d.ts +6 -2
- package/types/utils/settingsValidation/index.d.ts +0 -1
- package/cjs/storages/inMemory/uniqueKeysCacheInMemory.js +0 -73
- package/cjs/storages/inMemory/uniqueKeysCacheInMemoryCS.js +0 -78
- package/cjs/storages/inRedis/ImpressionCountsCacheInRedis.js +0 -49
- package/cjs/storages/inRedis/uniqueKeysCacheInRedis.js +0 -56
- package/cjs/sync/submitters/uniqueKeysSubmitter.js +0 -26
- package/cjs/trackers/strategy/strategyDebug.js +0 -25
- package/cjs/trackers/strategy/strategyNone.js +0 -29
- package/cjs/trackers/strategy/strategyOptimized.js +0 -35
- package/cjs/trackers/uniqueKeysTracker.js +0 -38
- package/esm/storages/inMemory/uniqueKeysCacheInMemory.js +0 -70
- package/esm/storages/inMemory/uniqueKeysCacheInMemoryCS.js +0 -75
- package/esm/storages/inRedis/ImpressionCountsCacheInRedis.js +0 -46
- package/esm/storages/inRedis/uniqueKeysCacheInRedis.js +0 -53
- package/esm/sync/submitters/uniqueKeysSubmitter.js +0 -22
- package/esm/trackers/strategy/strategyDebug.js +0 -21
- package/esm/trackers/strategy/strategyNone.js +0 -25
- package/esm/trackers/strategy/strategyOptimized.js +0 -31
- package/esm/trackers/uniqueKeysTracker.js +0 -34
- package/src/storages/inMemory/uniqueKeysCacheInMemory.ts +0 -82
- package/src/storages/inMemory/uniqueKeysCacheInMemoryCS.ts +0 -88
- package/src/storages/inRedis/ImpressionCountsCacheInRedis.ts +0 -51
- package/src/storages/inRedis/uniqueKeysCacheInRedis.ts +0 -63
- package/src/sync/submitters/uniqueKeysSubmitter.ts +0 -35
- package/src/trackers/strategy/strategyDebug.ts +0 -28
- package/src/trackers/strategy/strategyNone.ts +0 -34
- package/src/trackers/strategy/strategyOptimized.ts +0 -42
- package/src/trackers/uniqueKeysTracker.ts +0 -48
- package/types/sdkClient/types.d.ts +0 -18
- package/types/storages/inMemory/CountsCacheInMemory.d.ts +0 -20
- package/types/storages/inMemory/LatenciesCacheInMemory.d.ts +0 -20
- package/types/storages/inMemory/uniqueKeysCacheInMemory.d.ts +0 -35
- package/types/storages/inMemory/uniqueKeysCacheInMemoryCS.d.ts +0 -37
- package/types/storages/inRedis/CountsCacheInRedis.d.ts +0 -9
- package/types/storages/inRedis/ImpressionCountsCacheInRedis.d.ts +0 -14
- package/types/storages/inRedis/LatenciesCacheInRedis.d.ts +0 -9
- package/types/storages/inRedis/uniqueKeysCacheInRedis.d.ts +0 -15
- package/types/sync/offline/LocalhostFromFile.d.ts +0 -2
- package/types/sync/offline/splitsParser/splitsParserFromFile.d.ts +0 -2
- package/types/sync/submitters/eventsSyncTask.d.ts +0 -8
- package/types/sync/submitters/impressionCountsSubmitterInRedis.d.ts +0 -5
- package/types/sync/submitters/impressionCountsSyncTask.d.ts +0 -13
- package/types/sync/submitters/impressionsSyncTask.d.ts +0 -14
- package/types/sync/submitters/metricsSyncTask.d.ts +0 -12
- package/types/sync/submitters/submitterSyncTask.d.ts +0 -10
- package/types/sync/submitters/uniqueKeysSubmitter.d.ts +0 -5
- package/types/sync/submitters/uniqueKeysSubmitterInRedis.d.ts +0 -5
- package/types/sync/syncTaskComposite.d.ts +0 -5
- package/types/trackers/filter/bloomFilter.d.ts +0 -10
- package/types/trackers/filter/dictionaryFilter.d.ts +0 -8
- package/types/trackers/filter/types.d.ts +0 -5
- package/types/trackers/strategy/strategyDebug.d.ts +0 -9
- package/types/trackers/strategy/strategyNone.d.ts +0 -10
- package/types/trackers/strategy/strategyOptimized.d.ts +0 -11
- package/types/trackers/uniqueKeysTracker.d.ts +0 -13
- package/types/utils/timeTracker/index.d.ts +0 -70
package/esm/sdkClient/client.js
CHANGED
|
@@ -6,6 +6,15 @@ import { validateTrafficTypeExistance } from '../utils/inputValidation/trafficTy
|
|
|
6
6
|
import { SDK_NOT_READY } from '../utils/labels';
|
|
7
7
|
import { CONTROL, TREATMENT, TREATMENTS, TREATMENT_WITH_CONFIG, TREATMENTS_WITH_CONFIG, TRACK } from '../utils/constants';
|
|
8
8
|
import { IMPRESSION, IMPRESSION_QUEUEING } from '../logger/constants';
|
|
9
|
+
import { isStorageSync } from '../trackers/impressionObserver/utils';
|
|
10
|
+
var treatmentNotReady = { treatment: CONTROL, label: SDK_NOT_READY };
|
|
11
|
+
function treatmentsNotReady(splitNames) {
|
|
12
|
+
var evaluations = {};
|
|
13
|
+
splitNames.forEach(function (splitName) {
|
|
14
|
+
evaluations[splitName] = treatmentNotReady;
|
|
15
|
+
});
|
|
16
|
+
return evaluations;
|
|
17
|
+
}
|
|
9
18
|
/**
|
|
10
19
|
* Creator of base client with getTreatments and track methods.
|
|
11
20
|
*/
|
|
@@ -22,7 +31,11 @@ export function clientFactory(params) {
|
|
|
22
31
|
stopTelemetryTracker(queue[0] && queue[0].label);
|
|
23
32
|
return treatment;
|
|
24
33
|
};
|
|
25
|
-
var evaluation =
|
|
34
|
+
var evaluation = readinessManager.isReady() || readinessManager.isReadyFromCache() ?
|
|
35
|
+
evaluateFeature(log, key, splitName, attributes, storage) :
|
|
36
|
+
isStorageSync(settings) ? // If the SDK is not ready, treatment may be incorrect due to having splits but not segments data, or storage is not connected
|
|
37
|
+
treatmentNotReady :
|
|
38
|
+
Promise.resolve(treatmentNotReady); // Promisify if async
|
|
26
39
|
return thenable(evaluation) ? evaluation.then(function (res) { return wrapUp(res); }) : wrapUp(evaluation);
|
|
27
40
|
}
|
|
28
41
|
function getTreatmentWithConfig(key, splitName, attributes) {
|
|
@@ -41,7 +54,11 @@ export function clientFactory(params) {
|
|
|
41
54
|
stopTelemetryTracker(queue[0] && queue[0].label);
|
|
42
55
|
return treatments;
|
|
43
56
|
};
|
|
44
|
-
var evaluations =
|
|
57
|
+
var evaluations = readinessManager.isReady() || readinessManager.isReadyFromCache() ?
|
|
58
|
+
evaluateFeatures(log, key, splitNames, attributes, storage) :
|
|
59
|
+
isStorageSync(settings) ? // If the SDK is not ready, treatment may be incorrect due to having splits but not segments data, or storage is not connected
|
|
60
|
+
treatmentsNotReady(splitNames) :
|
|
61
|
+
Promise.resolve(treatmentsNotReady(splitNames)); // Promisify if async
|
|
45
62
|
return thenable(evaluations) ? evaluations.then(function (res) { return wrapUp(res); }) : wrapUp(evaluations);
|
|
46
63
|
}
|
|
47
64
|
function getTreatmentsWithConfig(key, splitNames, attributes) {
|
|
@@ -49,13 +66,8 @@ export function clientFactory(params) {
|
|
|
49
66
|
}
|
|
50
67
|
// Internal function
|
|
51
68
|
function processEvaluation(evaluation, splitName, key, attributes, withConfig, invokingMethodName, queue) {
|
|
52
|
-
var isSdkReady = readinessManager.isReady() || readinessManager.isReadyFromCache();
|
|
53
69
|
var matchingKey = getMatching(key);
|
|
54
70
|
var bucketingKey = getBucketing(key);
|
|
55
|
-
// If the SDK was not ready, treatment may be incorrect due to having Splits but not segments data.
|
|
56
|
-
if (!isSdkReady) {
|
|
57
|
-
evaluation = { treatment: CONTROL, label: SDK_NOT_READY };
|
|
58
|
-
}
|
|
59
71
|
var treatment = evaluation.treatment, label = evaluation.label, changeNumber = evaluation.changeNumber, _a = evaluation.config, config = _a === void 0 ? null : _a;
|
|
60
72
|
log.info(IMPRESSION, [splitName, matchingKey, treatment, label]);
|
|
61
73
|
if (validateSplitExistance(log, readinessManager, splitName, label, invokingMethodName)) {
|
|
@@ -6,7 +6,7 @@ import { clientInputValidationDecorator } from './clientInputValidation';
|
|
|
6
6
|
* Creates an Sdk client, i.e., a base client with status and destroy interface
|
|
7
7
|
*/
|
|
8
8
|
export function sdkClientFactory(params, isSharedClient) {
|
|
9
|
-
var sdkReadinessManager = params.sdkReadinessManager, syncManager = params.syncManager, storage = params.storage, signalListener = params.signalListener, settings = params.settings, telemetryTracker = params.telemetryTracker
|
|
9
|
+
var sdkReadinessManager = params.sdkReadinessManager, syncManager = params.syncManager, storage = params.storage, signalListener = params.signalListener, settings = params.settings, telemetryTracker = params.telemetryTracker;
|
|
10
10
|
return objectAssign(
|
|
11
11
|
// Proto-linkage of the readiness Event Emitter
|
|
12
12
|
Object.create(sdkReadinessManager.sdkStatus),
|
|
@@ -28,8 +28,6 @@ export function sdkClientFactory(params, isSharedClient) {
|
|
|
28
28
|
// Release the API Key if it is the main client
|
|
29
29
|
if (!isSharedClient)
|
|
30
30
|
releaseApiKey(settings.core.authorizationKey);
|
|
31
|
-
if (uniqueKeysTracker)
|
|
32
|
-
uniqueKeysTracker.stop();
|
|
33
31
|
// Cleanup storage
|
|
34
32
|
return storage.destroy();
|
|
35
33
|
});
|
package/esm/sdkFactory/index.js
CHANGED
|
@@ -10,16 +10,11 @@ import { NEW_FACTORY, RETRIEVE_MANAGER } from '../logger/constants';
|
|
|
10
10
|
import { metadataBuilder } from '../storages/metadataBuilder';
|
|
11
11
|
import { SDK_SPLITS_ARRIVED, SDK_SEGMENTS_ARRIVED } from '../readiness/constants';
|
|
12
12
|
import { objectAssign } from '../utils/lang/objectAssign';
|
|
13
|
-
import { strategyDebugFactory } from '../trackers/strategy/strategyDebug';
|
|
14
|
-
import { strategyOptimizedFactory } from '../trackers/strategy/strategyOptimized';
|
|
15
|
-
import { strategyNoneFactory } from '../trackers/strategy/strategyNone';
|
|
16
|
-
import { uniqueKeysTrackerFactory } from '../trackers/uniqueKeysTracker';
|
|
17
|
-
import { NONE, OPTIMIZED } from '../utils/constants';
|
|
18
13
|
/**
|
|
19
14
|
* Modular SDK factory
|
|
20
15
|
*/
|
|
21
16
|
export function sdkFactory(params) {
|
|
22
|
-
var settings = params.settings, platform = params.platform, storageFactory = params.storageFactory, splitApiFactory = params.splitApiFactory, extraProps = params.extraProps, syncManagerFactory = params.syncManagerFactory, SignalListener = params.SignalListener, impressionsObserverFactory = params.impressionsObserverFactory, integrationsManagerFactory = params.integrationsManagerFactory, sdkManagerFactory = params.sdkManagerFactory, sdkClientMethodFactory = params.sdkClientMethodFactory
|
|
17
|
+
var settings = params.settings, platform = params.platform, storageFactory = params.storageFactory, splitApiFactory = params.splitApiFactory, extraProps = params.extraProps, syncManagerFactory = params.syncManagerFactory, SignalListener = params.SignalListener, impressionsObserverFactory = params.impressionsObserverFactory, integrationsManagerFactory = params.integrationsManagerFactory, sdkManagerFactory = params.sdkManagerFactory, sdkClientMethodFactory = params.sdkClientMethodFactory;
|
|
23
18
|
var log = settings.log;
|
|
24
19
|
// @TODO handle non-recoverable errors, such as, global `fetch` not available, invalid API Key, etc.
|
|
25
20
|
// On non-recoverable errors, we should mark the SDK as destroyed and not start synchronization.
|
|
@@ -31,17 +26,12 @@ export function sdkFactory(params) {
|
|
|
31
26
|
var storageFactoryParams = {
|
|
32
27
|
impressionsQueueSize: settings.scheduler.impressionsQueueSize,
|
|
33
28
|
eventsQueueSize: settings.scheduler.eventsQueueSize,
|
|
34
|
-
uniqueKeysCacheSize: settings.scheduler.uniqueKeysCacheSize,
|
|
35
|
-
impressionCountsQueueSize: settings.scheduler.impressionCountsQueueSize,
|
|
36
|
-
impressionCountsRefreshRate: settings.scheduler.impressionCountsRefreshRate,
|
|
37
|
-
uniqueKeysRefreshRate: settings.scheduler.uniqueKeysRefreshRate,
|
|
38
29
|
optimize: shouldBeOptimized(settings),
|
|
39
30
|
// ATM, only used by InLocalStorage
|
|
40
31
|
matchingKey: getMatching(settings.core.key),
|
|
41
32
|
splitFiltersValidation: settings.sync.__splitFiltersValidation,
|
|
42
33
|
// ATM, only used by PluggableStorage
|
|
43
34
|
mode: settings.mode,
|
|
44
|
-
impressionsMode: settings.sync.impressionsMode,
|
|
45
35
|
// Callback used to emit SDK_READY in consumer mode, where `syncManagerFactory` is undefined,
|
|
46
36
|
// or partial consumer mode, where it only has submitters, and therefore it doesn't emit readiness events.
|
|
47
37
|
onReadyCb: function (error) {
|
|
@@ -57,24 +47,13 @@ export function sdkFactory(params) {
|
|
|
57
47
|
// @TODO add support for dataloader: `if (params.dataLoader) params.dataLoader(storage);`
|
|
58
48
|
var telemetryTracker = telemetryTrackerFactory(storage.telemetry, platform.now);
|
|
59
49
|
var integrationsManager = integrationsManagerFactory && integrationsManagerFactory({ settings: settings, storage: storage, telemetryTracker: telemetryTracker });
|
|
60
|
-
|
|
61
|
-
var
|
|
62
|
-
var
|
|
63
|
-
switch (storageFactoryParams.impressionsMode) {
|
|
64
|
-
case OPTIMIZED:
|
|
65
|
-
strategy = strategyOptimizedFactory(observer, storage.impressionCounts);
|
|
66
|
-
break;
|
|
67
|
-
case NONE:
|
|
68
|
-
strategy = strategyNoneFactory(storage.impressionCounts, uniqueKeysTracker);
|
|
69
|
-
break;
|
|
70
|
-
default:
|
|
71
|
-
strategy = strategyDebugFactory(observer);
|
|
72
|
-
}
|
|
73
|
-
var impressionsTracker = impressionsTrackerFactory(settings, storage.impressions, strategy, integrationsManager, storage.telemetry);
|
|
50
|
+
// trackers
|
|
51
|
+
var observer = impressionsObserverFactory && impressionsObserverFactory();
|
|
52
|
+
var impressionsTracker = impressionsTrackerFactory(settings, storage.impressions, integrationsManager, observer, storage.impressionCounts, storage.telemetry);
|
|
74
53
|
var eventTracker = eventTrackerFactory(settings, storage.events, integrationsManager, storage.telemetry);
|
|
75
54
|
// splitApi is used by SyncManager and Browser signal listener
|
|
76
55
|
var splitApi = splitApiFactory && splitApiFactory(settings, platform, telemetryTracker);
|
|
77
|
-
var ctx = { splitApi: splitApi, eventTracker: eventTracker, impressionsTracker: impressionsTracker, telemetryTracker: telemetryTracker,
|
|
56
|
+
var ctx = { splitApi: splitApi, eventTracker: eventTracker, impressionsTracker: impressionsTracker, telemetryTracker: telemetryTracker, sdkReadinessManager: sdkReadinessManager, readiness: readiness, settings: settings, storage: storage, platform: platform };
|
|
78
57
|
var syncManager = syncManagerFactory && syncManagerFactory(ctx);
|
|
79
58
|
ctx.syncManager = syncManager;
|
|
80
59
|
var signalListener = SignalListener && new SignalListener(syncManager, settings, storage, splitApi);
|
package/esm/services/splitApi.js
CHANGED
|
@@ -87,33 +87,13 @@ export function splitApiFactory(settings, platform, telemetryTracker) {
|
|
|
87
87
|
var url = urls.events + "/testImpressions/count";
|
|
88
88
|
return splitHttpClient(url, { method: 'POST', body: body, headers: headers }, telemetryTracker.trackHttp(IMPRESSIONS_COUNT));
|
|
89
89
|
},
|
|
90
|
-
|
|
91
|
-
* Post unique keys for client side.
|
|
92
|
-
*
|
|
93
|
-
* @param body unique keys payload
|
|
94
|
-
* @param headers Optionals headers to overwrite default ones. For example, it is used in producer mode to overwrite metadata headers.
|
|
95
|
-
*/
|
|
96
|
-
postUniqueKeysBulkCs: function (body, headers) {
|
|
97
|
-
var url = urls.telemetry + "/v1/keys/cs";
|
|
98
|
-
return splitHttpClient(url, { method: 'POST', body: body, headers: headers }, telemetryTracker.trackHttp(TELEMETRY));
|
|
99
|
-
},
|
|
100
|
-
/**
|
|
101
|
-
* Post unique keys for server side.
|
|
102
|
-
*
|
|
103
|
-
* @param body unique keys payload
|
|
104
|
-
* @param headers Optionals headers to overwrite default ones. For example, it is used in producer mode to overwrite metadata headers.
|
|
105
|
-
*/
|
|
106
|
-
postUniqueKeysBulkSs: function (body, headers) {
|
|
107
|
-
var url = urls.telemetry + "/v1/keys/ss";
|
|
108
|
-
return splitHttpClient(url, { method: 'POST', body: body, headers: headers }, telemetryTracker.trackHttp(TELEMETRY));
|
|
109
|
-
},
|
|
110
|
-
postMetricsConfig: function (body) {
|
|
90
|
+
postMetricsConfig: function (body, headers) {
|
|
111
91
|
var url = urls.telemetry + "/v1/metrics/config";
|
|
112
|
-
return splitHttpClient(url, { method: 'POST', body: body }, telemetryTracker.trackHttp(TELEMETRY), true);
|
|
92
|
+
return splitHttpClient(url, { method: 'POST', body: body, headers: headers }, telemetryTracker.trackHttp(TELEMETRY), true);
|
|
113
93
|
},
|
|
114
|
-
postMetricsUsage: function (body) {
|
|
94
|
+
postMetricsUsage: function (body, headers) {
|
|
115
95
|
var url = urls.telemetry + "/v1/metrics/usage";
|
|
116
|
-
return splitHttpClient(url, { method: 'POST', body: body }, telemetryTracker.trackHttp(TELEMETRY), true);
|
|
96
|
+
return splitHttpClient(url, { method: 'POST', body: body, headers: headers }, telemetryTracker.trackHttp(TELEMETRY), true);
|
|
117
97
|
}
|
|
118
98
|
};
|
|
119
99
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { __extends } from "tslib";
|
|
2
2
|
import { KeyBuilder } from './KeyBuilder';
|
|
3
|
-
|
|
3
|
+
import { MAX_LATENCY_BUCKET_COUNT } from './inMemory/TelemetryCacheInMemory';
|
|
4
|
+
var METHOD_NAMES = {
|
|
4
5
|
t: 'treatment',
|
|
5
6
|
ts: 'treatments',
|
|
6
7
|
tc: 'treatmentWithConfig',
|
|
@@ -11,7 +12,10 @@ var KeyBuilderSS = /** @class */ (function (_super) {
|
|
|
11
12
|
__extends(KeyBuilderSS, _super);
|
|
12
13
|
function KeyBuilderSS(prefix, metadata) {
|
|
13
14
|
var _this = _super.call(this, prefix) || this;
|
|
14
|
-
_this.
|
|
15
|
+
_this.latencyPrefix = _this.prefix + ".telemetry.latencies";
|
|
16
|
+
_this.exceptionPrefix = _this.prefix + ".telemetry.exceptions";
|
|
17
|
+
_this.initPrefix = _this.prefix + ".telemetry.init";
|
|
18
|
+
_this.versionablePrefix = metadata.s + "/" + metadata.n + "/" + metadata.i;
|
|
15
19
|
return _this;
|
|
16
20
|
}
|
|
17
21
|
KeyBuilderSS.prototype.buildRegisteredSegmentsKey = function () {
|
|
@@ -20,12 +24,6 @@ var KeyBuilderSS = /** @class */ (function (_super) {
|
|
|
20
24
|
KeyBuilderSS.prototype.buildImpressionsKey = function () {
|
|
21
25
|
return this.prefix + ".impressions";
|
|
22
26
|
};
|
|
23
|
-
KeyBuilderSS.prototype.buildImpressionsCountKey = function () {
|
|
24
|
-
return this.prefix + ".impressions.count";
|
|
25
|
-
};
|
|
26
|
-
KeyBuilderSS.prototype.buildUniqueKeysKey = function () {
|
|
27
|
-
return this.prefix + ".uniquekeys";
|
|
28
|
-
};
|
|
29
27
|
KeyBuilderSS.prototype.buildEventsKey = function () {
|
|
30
28
|
return this.prefix + ".events";
|
|
31
29
|
};
|
|
@@ -34,17 +32,49 @@ var KeyBuilderSS = /** @class */ (function (_super) {
|
|
|
34
32
|
};
|
|
35
33
|
/* Telemetry keys */
|
|
36
34
|
KeyBuilderSS.prototype.buildLatencyKey = function (method, bucket) {
|
|
37
|
-
return this.
|
|
35
|
+
return this.latencyPrefix + "::" + this.versionablePrefix + "/" + METHOD_NAMES[method] + "/" + bucket;
|
|
38
36
|
};
|
|
39
37
|
KeyBuilderSS.prototype.buildExceptionKey = function (method) {
|
|
40
|
-
return this.
|
|
38
|
+
return this.exceptionPrefix + "::" + this.versionablePrefix + "/" + METHOD_NAMES[method];
|
|
41
39
|
};
|
|
42
40
|
KeyBuilderSS.prototype.buildInitKey = function () {
|
|
43
|
-
return this.
|
|
44
|
-
};
|
|
45
|
-
KeyBuilderSS.prototype.buildVersionablePrefix = function () {
|
|
46
|
-
return this.metadata.s + "/" + this.metadata.n + "/" + this.metadata.i;
|
|
41
|
+
return this.initPrefix + "::" + this.versionablePrefix;
|
|
47
42
|
};
|
|
48
43
|
return KeyBuilderSS;
|
|
49
44
|
}(KeyBuilder));
|
|
50
45
|
export { KeyBuilderSS };
|
|
46
|
+
// Used by consumer methods of TelemetryCacheInRedis and TelemetryCachePluggable
|
|
47
|
+
var REVERSE_METHOD_NAMES = Object.keys(METHOD_NAMES).reduce(function (acc, key) {
|
|
48
|
+
acc[METHOD_NAMES[key]] = key;
|
|
49
|
+
return acc;
|
|
50
|
+
}, {});
|
|
51
|
+
export function parseMetadata(field) {
|
|
52
|
+
var parts = field.split('/');
|
|
53
|
+
if (parts.length !== 3)
|
|
54
|
+
return "invalid subsection count. Expected 4, got: " + parts.length;
|
|
55
|
+
var s = parts[0] /* metadata.s */, n = parts[1] /* metadata.n */, i = parts[2] /* metadata.i */;
|
|
56
|
+
return [JSON.stringify({ s: s, n: n, i: i })];
|
|
57
|
+
}
|
|
58
|
+
export function parseExceptionField(field) {
|
|
59
|
+
var parts = field.split('/');
|
|
60
|
+
if (parts.length !== 4)
|
|
61
|
+
return "invalid subsection count. Expected 4, got: " + parts.length;
|
|
62
|
+
var s = parts[0] /* metadata.s */, n = parts[1] /* metadata.n */, i = parts[2] /* metadata.i */, m = parts[3];
|
|
63
|
+
var method = REVERSE_METHOD_NAMES[m];
|
|
64
|
+
if (!method)
|
|
65
|
+
return "unknown method '" + m + "'";
|
|
66
|
+
return [JSON.stringify({ s: s, n: n, i: i }), method];
|
|
67
|
+
}
|
|
68
|
+
export function parseLatencyField(field) {
|
|
69
|
+
var parts = field.split('/');
|
|
70
|
+
if (parts.length !== 5)
|
|
71
|
+
return "invalid subsection count. Expected 5, got: " + parts.length;
|
|
72
|
+
var s = parts[0] /* metadata.s */, n = parts[1] /* metadata.n */, i = parts[2] /* metadata.i */, m = parts[3], b = parts[4];
|
|
73
|
+
var method = REVERSE_METHOD_NAMES[m];
|
|
74
|
+
if (!method)
|
|
75
|
+
return "unknown method '" + m + "'";
|
|
76
|
+
var bucket = parseInt(b);
|
|
77
|
+
if (isNaN(bucket) || bucket >= MAX_LATENCY_BUCKET_COUNT)
|
|
78
|
+
return "invalid bucket. Expected a number between 0 and 22, got: " + b;
|
|
79
|
+
return [JSON.stringify({ s: s, n: n, i: i }), method, bucket];
|
|
80
|
+
}
|
|
@@ -11,9 +11,8 @@ import { SplitsCacheInMemory } from '../inMemory/SplitsCacheInMemory';
|
|
|
11
11
|
import { DEFAULT_CACHE_EXPIRATION_IN_MILLIS } from '../../utils/constants/browser';
|
|
12
12
|
import { InMemoryStorageCSFactory } from '../inMemory/InMemoryStorageCS';
|
|
13
13
|
import { LOG_PREFIX } from './constants';
|
|
14
|
-
import {
|
|
14
|
+
import { STORAGE_LOCALSTORAGE } from '../../utils/constants';
|
|
15
15
|
import { shouldRecordTelemetry, TelemetryCacheInMemory } from '../inMemory/TelemetryCacheInMemory';
|
|
16
|
-
import { UniqueKeysCacheInMemoryCS } from '../inMemory/uniqueKeysCacheInMemoryCS';
|
|
17
16
|
/**
|
|
18
17
|
* InLocal storage factory for standalone client-side SplitFactory
|
|
19
18
|
*/
|
|
@@ -35,16 +34,13 @@ export function InLocalStorage(options) {
|
|
|
35
34
|
impressions: new ImpressionsCacheInMemory(params.impressionsQueueSize),
|
|
36
35
|
impressionCounts: params.optimize ? new ImpressionCountsCacheInMemory() : undefined,
|
|
37
36
|
events: new EventsCacheInMemory(params.eventsQueueSize),
|
|
38
|
-
telemetry:
|
|
39
|
-
uniqueKeys: params.impressionsMode === NONE ? new UniqueKeysCacheInMemoryCS() : undefined,
|
|
37
|
+
telemetry: shouldRecordTelemetry(params) ? new TelemetryCacheInMemory() : undefined,
|
|
40
38
|
destroy: function () {
|
|
41
|
-
var _a;
|
|
42
39
|
this.splits = new SplitsCacheInMemory();
|
|
43
40
|
this.segments = new MySegmentsCacheInMemory();
|
|
44
41
|
this.impressions.clear();
|
|
45
42
|
this.impressionCounts && this.impressionCounts.clear();
|
|
46
43
|
this.events.clear();
|
|
47
|
-
(_a = this.uniqueKeys) === null || _a === void 0 ? void 0 : _a.clear();
|
|
48
44
|
},
|
|
49
45
|
// When using shared instanciation with MEMORY we reuse everything but segments (they are customer per key).
|
|
50
46
|
shared: function (matchingKey) {
|
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
import { truncateTimeFrame } from '../../utils/time';
|
|
2
|
-
import { DEFAULT_CACHE_SIZE } from '../inRedis/constants';
|
|
3
2
|
var ImpressionCountsCacheInMemory = /** @class */ (function () {
|
|
4
|
-
function ImpressionCountsCacheInMemory(
|
|
5
|
-
if (impressionCountsCacheSize === void 0) { impressionCountsCacheSize = DEFAULT_CACHE_SIZE; }
|
|
3
|
+
function ImpressionCountsCacheInMemory() {
|
|
6
4
|
this.cache = {};
|
|
7
|
-
this.cacheSize = 0;
|
|
8
|
-
this.maxStorage = impressionCountsCacheSize;
|
|
9
5
|
}
|
|
10
6
|
/**
|
|
11
7
|
* Builds key to be stored in the cache with the featureName and the timeFrame truncated.
|
|
@@ -20,13 +16,6 @@ var ImpressionCountsCacheInMemory = /** @class */ (function () {
|
|
|
20
16
|
var key = this._makeKey(featureName, timeFrame);
|
|
21
17
|
var currentAmount = this.cache[key];
|
|
22
18
|
this.cache[key] = currentAmount ? currentAmount + amount : amount;
|
|
23
|
-
if (this.onFullQueue) {
|
|
24
|
-
this.cacheSize = this.cacheSize + amount;
|
|
25
|
-
if (this.cacheSize >= this.maxStorage) {
|
|
26
|
-
this.onFullQueue();
|
|
27
|
-
this.cacheSize = 0;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
19
|
};
|
|
31
20
|
/**
|
|
32
21
|
* Pop the collected data, used as payload for posting.
|
|
@@ -3,9 +3,8 @@ import { SegmentsCacheInMemory } from './SegmentsCacheInMemory';
|
|
|
3
3
|
import { ImpressionsCacheInMemory } from './ImpressionsCacheInMemory';
|
|
4
4
|
import { EventsCacheInMemory } from './EventsCacheInMemory';
|
|
5
5
|
import { ImpressionCountsCacheInMemory } from './ImpressionCountsCacheInMemory';
|
|
6
|
-
import {
|
|
7
|
-
import { TelemetryCacheInMemory } from './TelemetryCacheInMemory';
|
|
8
|
-
import { UniqueKeysCacheInMemory } from './uniqueKeysCacheInMemory';
|
|
6
|
+
import { STORAGE_MEMORY } from '../../utils/constants';
|
|
7
|
+
import { shouldRecordTelemetry, TelemetryCacheInMemory } from './TelemetryCacheInMemory';
|
|
9
8
|
/**
|
|
10
9
|
* InMemory storage factory for standalone server-side SplitFactory
|
|
11
10
|
*
|
|
@@ -16,19 +15,16 @@ export function InMemoryStorageFactory(params) {
|
|
|
16
15
|
splits: new SplitsCacheInMemory(),
|
|
17
16
|
segments: new SegmentsCacheInMemory(),
|
|
18
17
|
impressions: new ImpressionsCacheInMemory(params.impressionsQueueSize),
|
|
19
|
-
impressionCounts: params.
|
|
18
|
+
impressionCounts: params.optimize ? new ImpressionCountsCacheInMemory() : undefined,
|
|
20
19
|
events: new EventsCacheInMemory(params.eventsQueueSize),
|
|
21
|
-
telemetry: params
|
|
22
|
-
uniqueKeys: params.impressionsMode === NONE ? new UniqueKeysCacheInMemory(params.uniqueKeysCacheSize) : undefined,
|
|
20
|
+
telemetry: shouldRecordTelemetry(params) ? new TelemetryCacheInMemory() : undefined,
|
|
23
21
|
// When using MEMORY we should clean all the caches to leave them empty
|
|
24
22
|
destroy: function () {
|
|
25
|
-
var _a;
|
|
26
23
|
this.splits.clear();
|
|
27
24
|
this.segments.clear();
|
|
28
25
|
this.impressions.clear();
|
|
29
26
|
this.impressionCounts && this.impressionCounts.clear();
|
|
30
27
|
this.events.clear();
|
|
31
|
-
(_a = this.uniqueKeys) === null || _a === void 0 ? void 0 : _a.clear();
|
|
32
28
|
}
|
|
33
29
|
};
|
|
34
30
|
}
|
|
@@ -3,9 +3,8 @@ import { MySegmentsCacheInMemory } from './MySegmentsCacheInMemory';
|
|
|
3
3
|
import { ImpressionsCacheInMemory } from './ImpressionsCacheInMemory';
|
|
4
4
|
import { EventsCacheInMemory } from './EventsCacheInMemory';
|
|
5
5
|
import { ImpressionCountsCacheInMemory } from './ImpressionCountsCacheInMemory';
|
|
6
|
-
import {
|
|
6
|
+
import { STORAGE_MEMORY } from '../../utils/constants';
|
|
7
7
|
import { shouldRecordTelemetry, TelemetryCacheInMemory } from './TelemetryCacheInMemory';
|
|
8
|
-
import { UniqueKeysCacheInMemoryCS } from './uniqueKeysCacheInMemoryCS';
|
|
9
8
|
/**
|
|
10
9
|
* InMemory storage factory for standalone client-side SplitFactory
|
|
11
10
|
*
|
|
@@ -16,19 +15,16 @@ export function InMemoryStorageCSFactory(params) {
|
|
|
16
15
|
splits: new SplitsCacheInMemory(),
|
|
17
16
|
segments: new MySegmentsCacheInMemory(),
|
|
18
17
|
impressions: new ImpressionsCacheInMemory(params.impressionsQueueSize),
|
|
19
|
-
impressionCounts: params.
|
|
18
|
+
impressionCounts: params.optimize ? new ImpressionCountsCacheInMemory() : undefined,
|
|
20
19
|
events: new EventsCacheInMemory(params.eventsQueueSize),
|
|
21
|
-
telemetry:
|
|
22
|
-
uniqueKeys: params.impressionsMode === NONE ? new UniqueKeysCacheInMemoryCS(params.uniqueKeysCacheSize) : undefined,
|
|
20
|
+
telemetry: shouldRecordTelemetry(params) ? new TelemetryCacheInMemory() : undefined,
|
|
23
21
|
// When using MEMORY we should clean all the caches to leave them empty
|
|
24
22
|
destroy: function () {
|
|
25
|
-
var _a;
|
|
26
23
|
this.splits.clear();
|
|
27
24
|
this.segments.clear();
|
|
28
25
|
this.impressions.clear();
|
|
29
26
|
this.impressionCounts && this.impressionCounts.clear();
|
|
30
27
|
this.events.clear();
|
|
31
|
-
(_a = this.uniqueKeys) === null || _a === void 0 ? void 0 : _a.clear();
|
|
32
28
|
},
|
|
33
29
|
// When using shared instanciation with MEMORY we reuse everything but segments (they are unique per key)
|
|
34
30
|
shared: function () {
|
|
@@ -1,16 +1,18 @@
|
|
|
1
|
+
import { LOCALHOST_MODE } from '../../utils/constants';
|
|
1
2
|
import { findLatencyIndex } from '../findLatencyIndex';
|
|
2
3
|
var MAX_STREAMING_EVENTS = 20;
|
|
3
4
|
var MAX_TAGS = 10;
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
return
|
|
5
|
+
export var MAX_LATENCY_BUCKET_COUNT = 23;
|
|
6
|
+
export function newBuckets() {
|
|
7
|
+
return new Array(MAX_LATENCY_BUCKET_COUNT).fill(0);
|
|
7
8
|
}
|
|
8
9
|
var ACCEPTANCE_RANGE = 0.001;
|
|
9
10
|
/**
|
|
10
|
-
*
|
|
11
|
+
* Record telemetry if mode is not localhost.
|
|
12
|
+
* All factory instances track telemetry on server-side, and 0.1% on client-side.
|
|
11
13
|
*/
|
|
12
|
-
export function shouldRecordTelemetry() {
|
|
13
|
-
return Math.random() <= ACCEPTANCE_RANGE;
|
|
14
|
+
export function shouldRecordTelemetry(params) {
|
|
15
|
+
return params.mode !== LOCALHOST_MODE && (params.matchingKey === undefined || Math.random() <= ACCEPTANCE_RANGE);
|
|
14
16
|
}
|
|
15
17
|
var TelemetryCacheInMemory = /** @class */ (function () {
|
|
16
18
|
function TelemetryCacheInMemory() {
|
|
@@ -39,7 +39,7 @@ var EventsCacheInRedis = /** @class */ (function () {
|
|
|
39
39
|
};
|
|
40
40
|
/**
|
|
41
41
|
* Pop the given number of events from the storage.
|
|
42
|
-
* The returned promise rejects if the
|
|
42
|
+
* The returned promise rejects if the redis operation fails.
|
|
43
43
|
*
|
|
44
44
|
* NOTE: this method doesn't take into account MAX_EVENT_SIZE or MAX_QUEUE_BYTE_SIZE limits.
|
|
45
45
|
* It is the submitter responsability to handle that.
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
+
import { parseExceptionField, parseLatencyField, parseMetadata } from '../KeyBuilderSS';
|
|
1
2
|
import { findLatencyIndex } from '../findLatencyIndex';
|
|
2
3
|
import { getTelemetryConfigStats } from '../../sync/submitters/telemetrySubmitter';
|
|
3
4
|
import { CONSUMER_MODE, STORAGE_REDIS } from '../../utils/constants';
|
|
5
|
+
import { isNaNNumber, isString } from '../../utils/lang';
|
|
6
|
+
import { _Map } from '../../utils/lang/maps';
|
|
7
|
+
import { MAX_LATENCY_BUCKET_COUNT, newBuckets } from '../inMemory/TelemetryCacheInMemory';
|
|
4
8
|
var TelemetryCacheInRedis = /** @class */ (function () {
|
|
5
9
|
/**
|
|
6
10
|
* Create a Telemetry cache that uses Redis as storage.
|
|
@@ -28,6 +32,102 @@ var TelemetryCacheInRedis = /** @class */ (function () {
|
|
|
28
32
|
var value = JSON.stringify(getTelemetryConfigStats(CONSUMER_MODE, STORAGE_REDIS));
|
|
29
33
|
return this.redis.hset(key, field, value).catch(function () { });
|
|
30
34
|
};
|
|
35
|
+
/**
|
|
36
|
+
* Pop telemetry latencies.
|
|
37
|
+
* The returned promise rejects if redis operations fail.
|
|
38
|
+
*/
|
|
39
|
+
TelemetryCacheInRedis.prototype.popLatencies = function () {
|
|
40
|
+
var _this = this;
|
|
41
|
+
return this.redis.hgetall(this.keys.latencyPrefix).then(function (latencies) {
|
|
42
|
+
var result = new _Map();
|
|
43
|
+
Object.keys(latencies).forEach(function (field) {
|
|
44
|
+
var parsedField = parseLatencyField(field);
|
|
45
|
+
if (isString(parsedField)) {
|
|
46
|
+
_this.log.error("Ignoring invalid latency field: " + field + ": " + parsedField);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
var count = parseInt(latencies[field]);
|
|
50
|
+
if (isNaNNumber(count)) {
|
|
51
|
+
_this.log.error("Ignoring latency with invalid count: " + latencies[field]);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
var metadata = parsedField[0], method = parsedField[1], bucket = parsedField[2];
|
|
55
|
+
if (bucket >= MAX_LATENCY_BUCKET_COUNT) {
|
|
56
|
+
_this.log.error("Ignoring latency with invalid bucket: " + bucket);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
if (!result.has(metadata))
|
|
60
|
+
result.set(metadata, {
|
|
61
|
+
t: newBuckets(),
|
|
62
|
+
ts: newBuckets(),
|
|
63
|
+
tc: newBuckets(),
|
|
64
|
+
tcs: newBuckets(),
|
|
65
|
+
tr: newBuckets(),
|
|
66
|
+
});
|
|
67
|
+
result.get(metadata)[method][bucket] = count;
|
|
68
|
+
});
|
|
69
|
+
return _this.redis.del(_this.keys.latencyPrefix).then(function () { return result; });
|
|
70
|
+
});
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Pop telemetry exceptions.
|
|
74
|
+
* The returned promise rejects if redis operations fail.
|
|
75
|
+
*/
|
|
76
|
+
TelemetryCacheInRedis.prototype.popExceptions = function () {
|
|
77
|
+
var _this = this;
|
|
78
|
+
return this.redis.hgetall(this.keys.exceptionPrefix).then(function (exceptions) {
|
|
79
|
+
var result = new _Map();
|
|
80
|
+
Object.keys(exceptions).forEach(function (field) {
|
|
81
|
+
var parsedField = parseExceptionField(field);
|
|
82
|
+
if (isString(parsedField)) {
|
|
83
|
+
_this.log.error("Ignoring invalid exception field: " + field + ": " + parsedField);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
var count = parseInt(exceptions[field]);
|
|
87
|
+
if (isNaNNumber(count)) {
|
|
88
|
+
_this.log.error("Ignoring exception with invalid count: " + exceptions[field]);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
var metadata = parsedField[0], method = parsedField[1];
|
|
92
|
+
if (!result.has(metadata))
|
|
93
|
+
result.set(metadata, {
|
|
94
|
+
t: 0,
|
|
95
|
+
ts: 0,
|
|
96
|
+
tc: 0,
|
|
97
|
+
tcs: 0,
|
|
98
|
+
tr: 0,
|
|
99
|
+
});
|
|
100
|
+
result.get(metadata)[method] = count;
|
|
101
|
+
});
|
|
102
|
+
return _this.redis.del(_this.keys.exceptionPrefix).then(function () { return result; });
|
|
103
|
+
});
|
|
104
|
+
};
|
|
105
|
+
/**
|
|
106
|
+
* Pop telemetry configs.
|
|
107
|
+
* The returned promise rejects if redis operations fail.
|
|
108
|
+
*/
|
|
109
|
+
TelemetryCacheInRedis.prototype.popConfigs = function () {
|
|
110
|
+
var _this = this;
|
|
111
|
+
return this.redis.hgetall(this.keys.initPrefix).then(function (configs) {
|
|
112
|
+
var result = new _Map();
|
|
113
|
+
Object.keys(configs).forEach(function (field) {
|
|
114
|
+
var parsedField = parseMetadata(field);
|
|
115
|
+
if (isString(parsedField)) {
|
|
116
|
+
_this.log.error("Ignoring invalid config field: " + field + ": " + parsedField);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
var metadata = parsedField[0];
|
|
120
|
+
try {
|
|
121
|
+
var config = JSON.parse(configs[field]);
|
|
122
|
+
result.set(metadata, config);
|
|
123
|
+
}
|
|
124
|
+
catch (e) {
|
|
125
|
+
_this.log.error("Ignoring invalid config: " + configs[field]);
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
return _this.redis.del(_this.keys.initPrefix).then(function () { return result; });
|
|
129
|
+
});
|
|
130
|
+
};
|
|
31
131
|
return TelemetryCacheInRedis;
|
|
32
132
|
}());
|
|
33
133
|
export { TelemetryCacheInRedis };
|
|
@@ -5,10 +5,8 @@ import { SplitsCacheInRedis } from './SplitsCacheInRedis';
|
|
|
5
5
|
import { SegmentsCacheInRedis } from './SegmentsCacheInRedis';
|
|
6
6
|
import { ImpressionsCacheInRedis } from './ImpressionsCacheInRedis';
|
|
7
7
|
import { EventsCacheInRedis } from './EventsCacheInRedis';
|
|
8
|
-
import {
|
|
8
|
+
import { STORAGE_REDIS } from '../../utils/constants';
|
|
9
9
|
import { TelemetryCacheInRedis } from './TelemetryCacheInRedis';
|
|
10
|
-
import { UniqueKeysCacheInRedis } from './uniqueKeysCacheInRedis';
|
|
11
|
-
import { ImpressionCountsCacheInRedis } from './ImpressionCountsCacheInRedis';
|
|
12
10
|
/**
|
|
13
11
|
* InRedis storage factory for consumer server-side SplitFactory, that uses `Ioredis` Redis client for Node.
|
|
14
12
|
* @see {@link https://www.npmjs.com/package/ioredis}
|
|
@@ -17,19 +15,13 @@ export function InRedisStorage(options) {
|
|
|
17
15
|
if (options === void 0) { options = {}; }
|
|
18
16
|
var prefix = validatePrefix(options.prefix);
|
|
19
17
|
function InRedisStorageFactory(_a) {
|
|
20
|
-
var log = _a.log, metadata = _a.metadata, onReadyCb = _a.onReadyCb
|
|
18
|
+
var log = _a.log, metadata = _a.metadata, onReadyCb = _a.onReadyCb;
|
|
21
19
|
var keys = new KeyBuilderSS(prefix, metadata);
|
|
22
20
|
var redisClient = new RedisAdapter(log, options.options || {});
|
|
23
21
|
var telemetry = new TelemetryCacheInRedis(log, keys, redisClient);
|
|
24
|
-
var impressionCountsCache = impressionsMode !== DEBUG ? new ImpressionCountsCacheInRedis(log, keys.buildImpressionsCountKey(), redisClient, impressionCountsQueueSize, impressionCountsRefreshRate) : undefined;
|
|
25
|
-
var uniqueKeysCache = impressionsMode === NONE ? new UniqueKeysCacheInRedis(log, keys.buildUniqueKeysKey(), redisClient, uniqueKeysCacheSize, uniqueKeysRefreshRate) : undefined;
|
|
26
22
|
// subscription to Redis connect event in order to emit SDK_READY event on consumer mode
|
|
27
23
|
redisClient.on('connect', function () {
|
|
28
24
|
onReadyCb();
|
|
29
|
-
if (impressionCountsCache)
|
|
30
|
-
impressionCountsCache.start();
|
|
31
|
-
if (uniqueKeysCache)
|
|
32
|
-
uniqueKeysCache.start();
|
|
33
25
|
// Synchronize config
|
|
34
26
|
telemetry.recordConfig();
|
|
35
27
|
});
|
|
@@ -37,18 +29,12 @@ export function InRedisStorage(options) {
|
|
|
37
29
|
splits: new SplitsCacheInRedis(log, keys, redisClient),
|
|
38
30
|
segments: new SegmentsCacheInRedis(log, keys, redisClient),
|
|
39
31
|
impressions: new ImpressionsCacheInRedis(log, keys.buildImpressionsKey(), redisClient, metadata),
|
|
40
|
-
impressionCounts: impressionCountsCache,
|
|
41
32
|
events: new EventsCacheInRedis(log, keys.buildEventsKey(), redisClient, metadata),
|
|
42
33
|
telemetry: telemetry,
|
|
43
|
-
uniqueKeys: uniqueKeysCache,
|
|
44
34
|
// When using REDIS we should:
|
|
45
35
|
// 1- Disconnect from the storage
|
|
46
36
|
destroy: function () {
|
|
47
37
|
redisClient.disconnect();
|
|
48
|
-
if (impressionCountsCache)
|
|
49
|
-
impressionCountsCache.stop();
|
|
50
|
-
if (uniqueKeysCache)
|
|
51
|
-
uniqueKeysCache.stop();
|
|
52
38
|
// @TODO check that caches works as expected when redisClient is disconnected
|
|
53
39
|
}
|
|
54
40
|
};
|