@splitsoftware/splitio-commons 1.12.1-rc.6 → 1.12.1-rc.7
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 +4 -0
- package/cjs/storages/KeyBuilderCS.js +1 -1
- package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +1 -1
- package/cjs/storages/inRedis/TelemetryCacheInRedis.js +5 -16
- package/cjs/storages/pluggable/TelemetryCachePluggable.js +5 -16
- package/cjs/storages/pluggable/index.js +2 -0
- package/esm/storages/KeyBuilderCS.js +1 -1
- package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +1 -1
- package/esm/storages/inRedis/TelemetryCacheInRedis.js +5 -16
- package/esm/storages/pluggable/TelemetryCachePluggable.js +5 -16
- package/esm/storages/pluggable/index.js +2 -0
- package/package.json +1 -1
- package/src/storages/KeyBuilderCS.ts +1 -1
- package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +1 -1
- package/src/storages/inRedis/TelemetryCacheInRedis.ts +5 -17
- package/src/storages/pluggable/TelemetryCachePluggable.ts +5 -17
- package/src/storages/pluggable/index.ts +2 -0
package/CHANGES.txt
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
1.12.1 (December 12, 2023)
|
|
2
|
+
- Updated PluggableStorage, for producer mode, and LocalStorage, for standalone mode, to clear the storage before initiating the synchronization process if it was previously synchronized with a different SDK key (i.e., a different environment) or different Split Filter criteria.
|
|
3
|
+
- Bugfixing - Fixed an issue when tracking telemetry latencies for the new `getTreatmentsByFlagSet(s)` methods in Redis and Pluggable storages, which was causing the SDK to not track those stats.
|
|
4
|
+
|
|
1
5
|
1.12.0 (December 4, 2023)
|
|
2
6
|
- Added support for Flag Sets in "consumer" and "partial consumer" modes for Pluggable and Redis storages.
|
|
3
7
|
- Updated evaluation flow to log a warning when using flag sets that don't contain cached feature flags.
|
|
@@ -9,7 +9,7 @@ var KeyBuilderCS = /** @class */ (function (_super) {
|
|
|
9
9
|
function KeyBuilderCS(prefix, matchingKey) {
|
|
10
10
|
var _this = _super.call(this, prefix) || this;
|
|
11
11
|
_this.matchingKey = matchingKey;
|
|
12
|
-
_this.regexSplitsCacheKey = new RegExp("^" + prefix + "\\.");
|
|
12
|
+
_this.regexSplitsCacheKey = new RegExp("^" + prefix + "\\.(splits?|trafficType|flagSet)\\.");
|
|
13
13
|
return _this;
|
|
14
14
|
}
|
|
15
15
|
/**
|
|
@@ -126,7 +126,7 @@ var SplitsCacheInLocal = /** @class */ (function (_super) {
|
|
|
126
126
|
SplitsCacheInLocal.prototype.setChangeNumber = function (changeNumber) {
|
|
127
127
|
// when using a new split query, we must update it at the store
|
|
128
128
|
if (this.updateNewFilter) {
|
|
129
|
-
this.log.info(constants_1.LOG_PREFIX + 'SDK key or feature flag filter criteria was modified. Updating cache
|
|
129
|
+
this.log.info(constants_1.LOG_PREFIX + 'SDK key or feature flag filter criteria was modified. Updating cache');
|
|
130
130
|
var storageHashKey = this.keys.buildHashKey();
|
|
131
131
|
try {
|
|
132
132
|
localStorage.setItem(storageHashKey, this.storageHash);
|
|
@@ -59,15 +59,10 @@ var TelemetryCacheInRedis = /** @class */ (function () {
|
|
|
59
59
|
_this.log.error("Ignoring latency with invalid bucket: " + bucket);
|
|
60
60
|
return;
|
|
61
61
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
tc: (0, TelemetryCacheInMemory_1.newBuckets)(),
|
|
67
|
-
tcs: (0, TelemetryCacheInMemory_1.newBuckets)(),
|
|
68
|
-
tr: (0, TelemetryCacheInMemory_1.newBuckets)(),
|
|
69
|
-
});
|
|
70
|
-
result.get(metadata)[method][bucket] = count;
|
|
62
|
+
var methodLatencies = result.get(metadata) || {};
|
|
63
|
+
methodLatencies[method] = methodLatencies[method] || (0, TelemetryCacheInMemory_1.newBuckets)();
|
|
64
|
+
methodLatencies[method][bucket] = count;
|
|
65
|
+
result.set(metadata, methodLatencies);
|
|
71
66
|
});
|
|
72
67
|
return _this.redis.del(_this.keys.latencyPrefix).then(function () { return result; });
|
|
73
68
|
});
|
|
@@ -93,13 +88,7 @@ var TelemetryCacheInRedis = /** @class */ (function () {
|
|
|
93
88
|
}
|
|
94
89
|
var metadata = parsedField[0], method = parsedField[1];
|
|
95
90
|
if (!result.has(metadata))
|
|
96
|
-
result.set(metadata, {
|
|
97
|
-
t: 0,
|
|
98
|
-
ts: 0,
|
|
99
|
-
tc: 0,
|
|
100
|
-
tcs: 0,
|
|
101
|
-
tr: 0,
|
|
102
|
-
});
|
|
91
|
+
result.set(metadata, {});
|
|
103
92
|
result.get(metadata)[method] = count;
|
|
104
93
|
});
|
|
105
94
|
return _this.redis.del(_this.keys.exceptionPrefix).then(function () { return result; });
|
|
@@ -60,15 +60,10 @@ var TelemetryCachePluggable = /** @class */ (function () {
|
|
|
60
60
|
_this.log.error("Ignoring latency with invalid bucket: " + bucket);
|
|
61
61
|
continue;
|
|
62
62
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
tc: (0, TelemetryCacheInMemory_1.newBuckets)(),
|
|
68
|
-
tcs: (0, TelemetryCacheInMemory_1.newBuckets)(),
|
|
69
|
-
tr: (0, TelemetryCacheInMemory_1.newBuckets)(),
|
|
70
|
-
});
|
|
71
|
-
result.get(metadata)[method][bucket] = count;
|
|
63
|
+
var methodLatencies = result.get(metadata) || {};
|
|
64
|
+
methodLatencies[method] = methodLatencies[method] || (0, TelemetryCacheInMemory_1.newBuckets)();
|
|
65
|
+
methodLatencies[method][bucket] = count;
|
|
66
|
+
result.set(metadata, methodLatencies);
|
|
72
67
|
}
|
|
73
68
|
return Promise.all(latencyKeys.map(function (latencyKey) { return _this.wrapper.del(latencyKey); })).then(function () { return result; });
|
|
74
69
|
}) :
|
|
@@ -101,13 +96,7 @@ var TelemetryCachePluggable = /** @class */ (function () {
|
|
|
101
96
|
}
|
|
102
97
|
var metadata = parsedField[0], method = parsedField[1];
|
|
103
98
|
if (!result.has(metadata))
|
|
104
|
-
result.set(metadata, {
|
|
105
|
-
t: 0,
|
|
106
|
-
ts: 0,
|
|
107
|
-
tc: 0,
|
|
108
|
-
tcs: 0,
|
|
109
|
-
tr: 0,
|
|
110
|
-
});
|
|
99
|
+
result.set(metadata, {});
|
|
111
100
|
result.get(metadata)[method] = count;
|
|
112
101
|
}
|
|
113
102
|
return Promise.all(exceptionKeys.map(function (exceptionKey) { return _this.wrapper.del(exceptionKey); })).then(function () { return result; });
|
|
@@ -21,6 +21,7 @@ var UniqueKeysCachePluggable_1 = require("./UniqueKeysCachePluggable");
|
|
|
21
21
|
var UniqueKeysCacheInMemory_1 = require("../inMemory/UniqueKeysCacheInMemory");
|
|
22
22
|
var UniqueKeysCacheInMemoryCS_1 = require("../inMemory/UniqueKeysCacheInMemoryCS");
|
|
23
23
|
var utils_1 = require("../utils");
|
|
24
|
+
var constants_2 = require("../pluggable/constants");
|
|
24
25
|
var NO_VALID_WRAPPER = 'Expecting pluggable storage `wrapper` in options, but no valid wrapper instance was provided.';
|
|
25
26
|
var NO_VALID_WRAPPER_INTERFACE = 'The provided wrapper instance doesn’t follow the expected interface. Check our docs.';
|
|
26
27
|
/**
|
|
@@ -81,6 +82,7 @@ function PluggableStorage(options) {
|
|
|
81
82
|
return wrapper.get(keys.buildHashKey()).then(function (hash) {
|
|
82
83
|
var currentHash = (0, KeyBuilder_1.getStorageHash)(settings);
|
|
83
84
|
if (hash !== currentHash) {
|
|
85
|
+
log.info(constants_2.LOG_PREFIX + 'Storage HASH has changed (SDK key or feature flag filter criteria was modified). Clearing cache');
|
|
84
86
|
return wrapper.getKeysByPrefix(keys.prefix + ".").then(function (storageKeys) {
|
|
85
87
|
return Promise.all(storageKeys.map(function (storageKey) { return wrapper.del(storageKey); }));
|
|
86
88
|
}).then(function () { return wrapper.set(keys.buildHashKey(), currentHash); });
|
|
@@ -6,7 +6,7 @@ var KeyBuilderCS = /** @class */ (function (_super) {
|
|
|
6
6
|
function KeyBuilderCS(prefix, matchingKey) {
|
|
7
7
|
var _this = _super.call(this, prefix) || this;
|
|
8
8
|
_this.matchingKey = matchingKey;
|
|
9
|
-
_this.regexSplitsCacheKey = new RegExp("^" + prefix + "\\.");
|
|
9
|
+
_this.regexSplitsCacheKey = new RegExp("^" + prefix + "\\.(splits?|trafficType|flagSet)\\.");
|
|
10
10
|
return _this;
|
|
11
11
|
}
|
|
12
12
|
/**
|
|
@@ -123,7 +123,7 @@ var SplitsCacheInLocal = /** @class */ (function (_super) {
|
|
|
123
123
|
SplitsCacheInLocal.prototype.setChangeNumber = function (changeNumber) {
|
|
124
124
|
// when using a new split query, we must update it at the store
|
|
125
125
|
if (this.updateNewFilter) {
|
|
126
|
-
this.log.info(LOG_PREFIX + 'SDK key or feature flag filter criteria was modified. Updating cache
|
|
126
|
+
this.log.info(LOG_PREFIX + 'SDK key or feature flag filter criteria was modified. Updating cache');
|
|
127
127
|
var storageHashKey = this.keys.buildHashKey();
|
|
128
128
|
try {
|
|
129
129
|
localStorage.setItem(storageHashKey, this.storageHash);
|
|
@@ -56,15 +56,10 @@ var TelemetryCacheInRedis = /** @class */ (function () {
|
|
|
56
56
|
_this.log.error("Ignoring latency with invalid bucket: " + bucket);
|
|
57
57
|
return;
|
|
58
58
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
tc: newBuckets(),
|
|
64
|
-
tcs: newBuckets(),
|
|
65
|
-
tr: newBuckets(),
|
|
66
|
-
});
|
|
67
|
-
result.get(metadata)[method][bucket] = count;
|
|
59
|
+
var methodLatencies = result.get(metadata) || {};
|
|
60
|
+
methodLatencies[method] = methodLatencies[method] || newBuckets();
|
|
61
|
+
methodLatencies[method][bucket] = count;
|
|
62
|
+
result.set(metadata, methodLatencies);
|
|
68
63
|
});
|
|
69
64
|
return _this.redis.del(_this.keys.latencyPrefix).then(function () { return result; });
|
|
70
65
|
});
|
|
@@ -90,13 +85,7 @@ var TelemetryCacheInRedis = /** @class */ (function () {
|
|
|
90
85
|
}
|
|
91
86
|
var metadata = parsedField[0], method = parsedField[1];
|
|
92
87
|
if (!result.has(metadata))
|
|
93
|
-
result.set(metadata, {
|
|
94
|
-
t: 0,
|
|
95
|
-
ts: 0,
|
|
96
|
-
tc: 0,
|
|
97
|
-
tcs: 0,
|
|
98
|
-
tr: 0,
|
|
99
|
-
});
|
|
88
|
+
result.set(metadata, {});
|
|
100
89
|
result.get(metadata)[method] = count;
|
|
101
90
|
});
|
|
102
91
|
return _this.redis.del(_this.keys.exceptionPrefix).then(function () { return result; });
|
|
@@ -57,15 +57,10 @@ var TelemetryCachePluggable = /** @class */ (function () {
|
|
|
57
57
|
_this.log.error("Ignoring latency with invalid bucket: " + bucket);
|
|
58
58
|
continue;
|
|
59
59
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
tc: newBuckets(),
|
|
65
|
-
tcs: newBuckets(),
|
|
66
|
-
tr: newBuckets(),
|
|
67
|
-
});
|
|
68
|
-
result.get(metadata)[method][bucket] = count;
|
|
60
|
+
var methodLatencies = result.get(metadata) || {};
|
|
61
|
+
methodLatencies[method] = methodLatencies[method] || newBuckets();
|
|
62
|
+
methodLatencies[method][bucket] = count;
|
|
63
|
+
result.set(metadata, methodLatencies);
|
|
69
64
|
}
|
|
70
65
|
return Promise.all(latencyKeys.map(function (latencyKey) { return _this.wrapper.del(latencyKey); })).then(function () { return result; });
|
|
71
66
|
}) :
|
|
@@ -98,13 +93,7 @@ var TelemetryCachePluggable = /** @class */ (function () {
|
|
|
98
93
|
}
|
|
99
94
|
var metadata = parsedField[0], method = parsedField[1];
|
|
100
95
|
if (!result.has(metadata))
|
|
101
|
-
result.set(metadata, {
|
|
102
|
-
t: 0,
|
|
103
|
-
ts: 0,
|
|
104
|
-
tc: 0,
|
|
105
|
-
tcs: 0,
|
|
106
|
-
tr: 0,
|
|
107
|
-
});
|
|
96
|
+
result.set(metadata, {});
|
|
108
97
|
result.get(metadata)[method] = count;
|
|
109
98
|
}
|
|
110
99
|
return Promise.all(exceptionKeys.map(function (exceptionKey) { return _this.wrapper.del(exceptionKey); })).then(function () { return result; });
|
|
@@ -18,6 +18,7 @@ import { UniqueKeysCachePluggable } from './UniqueKeysCachePluggable';
|
|
|
18
18
|
import { UniqueKeysCacheInMemory } from '../inMemory/UniqueKeysCacheInMemory';
|
|
19
19
|
import { UniqueKeysCacheInMemoryCS } from '../inMemory/UniqueKeysCacheInMemoryCS';
|
|
20
20
|
import { metadataBuilder } from '../utils';
|
|
21
|
+
import { LOG_PREFIX } from '../pluggable/constants';
|
|
21
22
|
var NO_VALID_WRAPPER = 'Expecting pluggable storage `wrapper` in options, but no valid wrapper instance was provided.';
|
|
22
23
|
var NO_VALID_WRAPPER_INTERFACE = 'The provided wrapper instance doesn’t follow the expected interface. Check our docs.';
|
|
23
24
|
/**
|
|
@@ -78,6 +79,7 @@ export function PluggableStorage(options) {
|
|
|
78
79
|
return wrapper.get(keys.buildHashKey()).then(function (hash) {
|
|
79
80
|
var currentHash = getStorageHash(settings);
|
|
80
81
|
if (hash !== currentHash) {
|
|
82
|
+
log.info(LOG_PREFIX + 'Storage HASH has changed (SDK key or feature flag filter criteria was modified). Clearing cache');
|
|
81
83
|
return wrapper.getKeysByPrefix(keys.prefix + ".").then(function (storageKeys) {
|
|
82
84
|
return Promise.all(storageKeys.map(function (storageKey) { return wrapper.del(storageKey); }));
|
|
83
85
|
}).then(function () { return wrapper.set(keys.buildHashKey(), currentHash); });
|
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@ export class KeyBuilderCS extends KeyBuilder {
|
|
|
9
9
|
constructor(prefix: string, matchingKey: string) {
|
|
10
10
|
super(prefix);
|
|
11
11
|
this.matchingKey = matchingKey;
|
|
12
|
-
this.regexSplitsCacheKey = new RegExp(`^${prefix}\\.`);
|
|
12
|
+
this.regexSplitsCacheKey = new RegExp(`^${prefix}\\.(splits?|trafficType|flagSet)\\.`);
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
/**
|
|
@@ -146,7 +146,7 @@ export class SplitsCacheInLocal extends AbstractSplitsCacheSync {
|
|
|
146
146
|
|
|
147
147
|
// when using a new split query, we must update it at the store
|
|
148
148
|
if (this.updateNewFilter) {
|
|
149
|
-
this.log.info(LOG_PREFIX + 'SDK key or feature flag filter criteria was modified. Updating cache
|
|
149
|
+
this.log.info(LOG_PREFIX + 'SDK key or feature flag filter criteria was modified. Updating cache');
|
|
150
150
|
const storageHashKey = this.keys.buildHashKey();
|
|
151
151
|
try {
|
|
152
152
|
localStorage.setItem(storageHashKey, this.storageHash);
|
|
@@ -69,15 +69,10 @@ export class TelemetryCacheInRedis implements ITelemetryCacheAsync {
|
|
|
69
69
|
return;
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
tcs: newBuckets(),
|
|
77
|
-
tr: newBuckets(),
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
result.get(metadata)![method]![bucket] = count;
|
|
72
|
+
const methodLatencies = result.get(metadata) || {};
|
|
73
|
+
methodLatencies[method] = methodLatencies[method] || newBuckets();
|
|
74
|
+
methodLatencies[method]![bucket] = count;
|
|
75
|
+
result.set(metadata, methodLatencies);
|
|
81
76
|
});
|
|
82
77
|
|
|
83
78
|
return this.redis.del(this.keys.latencyPrefix).then(() => result);
|
|
@@ -109,14 +104,7 @@ export class TelemetryCacheInRedis implements ITelemetryCacheAsync {
|
|
|
109
104
|
|
|
110
105
|
const [metadata, method] = parsedField;
|
|
111
106
|
|
|
112
|
-
if (!result.has(metadata)) result.set(metadata, {
|
|
113
|
-
t: 0,
|
|
114
|
-
ts: 0,
|
|
115
|
-
tc: 0,
|
|
116
|
-
tcs: 0,
|
|
117
|
-
tr: 0,
|
|
118
|
-
});
|
|
119
|
-
|
|
107
|
+
if (!result.has(metadata)) result.set(metadata, {});
|
|
120
108
|
result.get(metadata)![method] = count;
|
|
121
109
|
});
|
|
122
110
|
|
|
@@ -68,15 +68,10 @@ export class TelemetryCachePluggable implements ITelemetryCacheAsync {
|
|
|
68
68
|
continue;
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
tcs: newBuckets(),
|
|
76
|
-
tr: newBuckets(),
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
result.get(metadata)![method]![bucket] = count;
|
|
71
|
+
const methodLatencies = result.get(metadata) || {};
|
|
72
|
+
methodLatencies[method] = methodLatencies[method] || newBuckets();
|
|
73
|
+
methodLatencies[method]![bucket] = count;
|
|
74
|
+
result.set(metadata, methodLatencies);
|
|
80
75
|
}
|
|
81
76
|
|
|
82
77
|
return Promise.all(latencyKeys.map((latencyKey) => this.wrapper.del(latencyKey))).then(() => result);
|
|
@@ -115,14 +110,7 @@ export class TelemetryCachePluggable implements ITelemetryCacheAsync {
|
|
|
115
110
|
|
|
116
111
|
const [metadata, method] = parsedField;
|
|
117
112
|
|
|
118
|
-
if (!result.has(metadata)) result.set(metadata, {
|
|
119
|
-
t: 0,
|
|
120
|
-
ts: 0,
|
|
121
|
-
tc: 0,
|
|
122
|
-
tcs: 0,
|
|
123
|
-
tr: 0,
|
|
124
|
-
});
|
|
125
|
-
|
|
113
|
+
if (!result.has(metadata)) result.set(metadata, {});
|
|
126
114
|
result.get(metadata)![method] = count;
|
|
127
115
|
}
|
|
128
116
|
|
|
@@ -19,6 +19,7 @@ import { UniqueKeysCachePluggable } from './UniqueKeysCachePluggable';
|
|
|
19
19
|
import { UniqueKeysCacheInMemory } from '../inMemory/UniqueKeysCacheInMemory';
|
|
20
20
|
import { UniqueKeysCacheInMemoryCS } from '../inMemory/UniqueKeysCacheInMemoryCS';
|
|
21
21
|
import { metadataBuilder } from '../utils';
|
|
22
|
+
import { LOG_PREFIX } from '../pluggable/constants';
|
|
22
23
|
|
|
23
24
|
const NO_VALID_WRAPPER = 'Expecting pluggable storage `wrapper` in options, but no valid wrapper instance was provided.';
|
|
24
25
|
const NO_VALID_WRAPPER_INTERFACE = 'The provided wrapper instance doesn’t follow the expected interface. Check our docs.';
|
|
@@ -95,6 +96,7 @@ export function PluggableStorage(options: PluggableStorageOptions): IStorageAsyn
|
|
|
95
96
|
return wrapper.get(keys.buildHashKey()).then((hash) => {
|
|
96
97
|
const currentHash = getStorageHash(settings);
|
|
97
98
|
if (hash !== currentHash) {
|
|
99
|
+
log.info(LOG_PREFIX + 'Storage HASH has changed (SDK key or feature flag filter criteria was modified). Clearing cache');
|
|
98
100
|
return wrapper.getKeysByPrefix(`${keys.prefix}.`).then(storageKeys => {
|
|
99
101
|
return Promise.all(storageKeys.map(storageKey => wrapper.del(storageKey)));
|
|
100
102
|
}).then(() => wrapper.set(keys.buildHashKey(), currentHash));
|