@splitsoftware/splitio-commons 1.3.2-rc.7 → 1.4.1-rc.1
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/listeners/browser.js +1 -1
- package/cjs/logger/messages/warn.js +1 -1
- package/cjs/storages/inMemory/EventsCacheInMemory.js +5 -3
- package/cjs/storages/inMemory/ImpressionCountsCacheInMemory.js +12 -4
- package/cjs/storages/inMemory/ImpressionsCacheInMemory.js +5 -3
- package/cjs/sync/submitters/submitter.js +10 -6
- package/cjs/sync/submitters/telemetrySubmitter.js +2 -2
- package/esm/listeners/browser.js +1 -1
- package/esm/logger/messages/warn.js +1 -1
- package/esm/storages/inMemory/EventsCacheInMemory.js +5 -3
- package/esm/storages/inMemory/ImpressionCountsCacheInMemory.js +12 -4
- package/esm/storages/inMemory/ImpressionsCacheInMemory.js +5 -3
- package/esm/sync/submitters/submitter.js +10 -6
- package/esm/sync/submitters/telemetrySubmitter.js +2 -2
- package/package.json +1 -1
- package/src/listeners/browser.ts +1 -1
- package/src/logger/messages/warn.ts +1 -1
- package/src/storages/inMemory/EventsCacheInMemory.ts +5 -3
- package/src/storages/inMemory/ImpressionCountsCacheInMemory.ts +14 -4
- package/src/storages/inMemory/ImpressionsCacheInMemory.ts +5 -3
- package/src/storages/types.ts +3 -4
- package/src/sync/submitters/submitter.ts +9 -5
- package/src/sync/submitters/telemetrySubmitter.ts +2 -2
- package/types/storages/inMemory/EventsCacheInMemory.d.ts +2 -2
- package/types/storages/inMemory/ImpressionCountsCacheInMemory.d.ts +9 -3
- package/types/storages/inMemory/ImpressionsCacheInMemory.d.ts +2 -2
- package/types/storages/types.d.ts +2 -3
- package/types/sync/submitters/telemetrySubmitter.d.ts +2 -2
package/CHANGES.txt
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
1.4.1 (June 13, 2022)
|
|
2
|
+
- Bugfixing - Updated submitters logic, to avoid dropping impressions and events that are being tracked while POST request is pending.
|
|
3
|
+
|
|
1
4
|
1.4.0 (May 24, 2022)
|
|
2
5
|
- Added `scheduler.telemetryRefreshRate` property to SDK configuration, and deprecated `scheduler.metricsRefreshRate` property.
|
|
3
6
|
- Updated SDK telemetry storage, metrics and updater to be more effective and send less often.
|
package/cjs/listeners/browser.js
CHANGED
|
@@ -77,7 +77,7 @@ var BrowserSignalListener = /** @class */ (function () {
|
|
|
77
77
|
BrowserSignalListener.prototype._flushData = function (url, cache, postService, fromCacheToPayload, extraMetadata) {
|
|
78
78
|
// if there is data in cache, send it to backend
|
|
79
79
|
if (!cache.isEmpty()) {
|
|
80
|
-
var dataPayload = fromCacheToPayload ? fromCacheToPayload(cache.
|
|
80
|
+
var dataPayload = fromCacheToPayload ? fromCacheToPayload(cache.pop()) : cache.pop();
|
|
81
81
|
if (!this._sendBeacon(url, dataPayload, extraMetadata)) {
|
|
82
82
|
postService(JSON.stringify(dataPayload)).catch(function () { }); // no-op just to catch a possible exception
|
|
83
83
|
}
|
|
@@ -14,7 +14,7 @@ exports.codesWarn = error_1.codesError.concat([
|
|
|
14
14
|
[c.STREAMING_PARSING_ERROR_FAILS, c.LOG_PREFIX_SYNC_STREAMING + 'Error parsing SSE error notification: %s'],
|
|
15
15
|
[c.STREAMING_PARSING_MESSAGE_FAILS, c.LOG_PREFIX_SYNC_STREAMING + 'Error parsing SSE message notification: %s'],
|
|
16
16
|
[c.STREAMING_FALLBACK, c.LOG_PREFIX_SYNC_STREAMING + 'Falling back to polling mode. Reason: %s'],
|
|
17
|
-
[c.SUBMITTERS_PUSH_FAILS, c.LOG_PREFIX_SYNC_SUBMITTERS + '
|
|
17
|
+
[c.SUBMITTERS_PUSH_FAILS, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Dropping %s after retry. Reason: %s.'],
|
|
18
18
|
[c.SUBMITTERS_PUSH_RETRY, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Failed to push %s, keeping data to retry on next iteration. Reason: %s.'],
|
|
19
19
|
// client status
|
|
20
20
|
[c.CLIENT_NOT_READY, '%s: the SDK is not ready, results may be incorrect. Make sure to wait for SDK readiness before using this method.'],
|
|
@@ -35,10 +35,12 @@ var EventsCacheInMemory = /** @class */ (function () {
|
|
|
35
35
|
this.queueByteSize = 0;
|
|
36
36
|
};
|
|
37
37
|
/**
|
|
38
|
-
*
|
|
38
|
+
* Pop the collected data, used as payload for posting.
|
|
39
39
|
*/
|
|
40
|
-
EventsCacheInMemory.prototype.
|
|
41
|
-
|
|
40
|
+
EventsCacheInMemory.prototype.pop = function () {
|
|
41
|
+
var data = this.queue;
|
|
42
|
+
this.clear();
|
|
43
|
+
return data;
|
|
42
44
|
};
|
|
43
45
|
/**
|
|
44
46
|
* Check if the cache is empty.
|
|
@@ -21,14 +21,22 @@ var ImpressionCountsCacheInMemory = /** @class */ (function () {
|
|
|
21
21
|
this.cache[key] = currentAmount ? currentAmount + amount : amount;
|
|
22
22
|
};
|
|
23
23
|
/**
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
ImpressionCountsCacheInMemory.prototype.
|
|
27
|
-
|
|
24
|
+
* Pop the collected data, used as payload for posting.
|
|
25
|
+
*/
|
|
26
|
+
ImpressionCountsCacheInMemory.prototype.pop = function () {
|
|
27
|
+
var data = this.cache;
|
|
28
|
+
this.clear();
|
|
29
|
+
return data;
|
|
28
30
|
};
|
|
31
|
+
/**
|
|
32
|
+
* Clear the data stored on the cache.
|
|
33
|
+
*/
|
|
29
34
|
ImpressionCountsCacheInMemory.prototype.clear = function () {
|
|
30
35
|
this.cache = {};
|
|
31
36
|
};
|
|
37
|
+
/**
|
|
38
|
+
* Check if the cache is empty.
|
|
39
|
+
*/
|
|
32
40
|
ImpressionCountsCacheInMemory.prototype.isEmpty = function () {
|
|
33
41
|
return Object.keys(this.cache).length === 0;
|
|
34
42
|
};
|
|
@@ -33,10 +33,12 @@ var ImpressionsCacheInMemory = /** @class */ (function () {
|
|
|
33
33
|
this.queue = [];
|
|
34
34
|
};
|
|
35
35
|
/**
|
|
36
|
-
*
|
|
36
|
+
* Pop the collected data, used as payload for posting.
|
|
37
37
|
*/
|
|
38
|
-
ImpressionsCacheInMemory.prototype.
|
|
39
|
-
|
|
38
|
+
ImpressionsCacheInMemory.prototype.pop = function () {
|
|
39
|
+
var data = this.queue;
|
|
40
|
+
this.clear();
|
|
41
|
+
return data;
|
|
40
42
|
};
|
|
41
43
|
/**
|
|
42
44
|
* Check if the cache is empty.
|
|
@@ -10,26 +10,30 @@ function submitterFactory(log, postClient, sourceCache, postRate, dataName, from
|
|
|
10
10
|
) {
|
|
11
11
|
if (maxRetries === void 0) { maxRetries = 0; }
|
|
12
12
|
var retries = 0;
|
|
13
|
+
var data;
|
|
13
14
|
function postData() {
|
|
14
|
-
if (
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
if (!data) {
|
|
16
|
+
if (sourceCache.isEmpty())
|
|
17
|
+
return Promise.resolve();
|
|
18
|
+
// we clear the cache to track new items, while `data` is used for retries
|
|
19
|
+
data = sourceCache.pop();
|
|
20
|
+
}
|
|
17
21
|
// @ts-ignore
|
|
18
22
|
var dataCountMessage = typeof data.length === 'number' ? data.length + " " + dataName : dataName;
|
|
19
23
|
log[debugLogs ? 'debug' : 'info'](constants_1.SUBMITTERS_PUSH, [dataCountMessage]);
|
|
20
24
|
var jsonPayload = JSON.stringify(fromCacheToPayload ? fromCacheToPayload(data) : data);
|
|
21
25
|
if (!maxRetries)
|
|
22
|
-
|
|
26
|
+
data = undefined;
|
|
23
27
|
return postClient(jsonPayload).then(function () {
|
|
24
28
|
retries = 0;
|
|
25
|
-
|
|
29
|
+
data = undefined;
|
|
26
30
|
}).catch(function (err) {
|
|
27
31
|
if (!maxRetries) {
|
|
28
32
|
log[debugLogs ? 'debug' : 'warn'](constants_1.SUBMITTERS_PUSH_FAILS, [dataCountMessage, err]);
|
|
29
33
|
}
|
|
30
34
|
else if (retries === maxRetries) {
|
|
31
35
|
retries = 0;
|
|
32
|
-
|
|
36
|
+
data = undefined;
|
|
33
37
|
log[debugLogs ? 'debug' : 'warn'](constants_1.SUBMITTERS_PUSH_FAILS, [dataCountMessage, err]);
|
|
34
38
|
}
|
|
35
39
|
else {
|
|
@@ -17,7 +17,7 @@ function telemetryCacheStatsAdapter(telemetry, splits, segments) {
|
|
|
17
17
|
isEmpty: function () { return false; },
|
|
18
18
|
clear: function () { },
|
|
19
19
|
// @TODO consider moving inside telemetry cache for code size reduction
|
|
20
|
-
|
|
20
|
+
pop: function () {
|
|
21
21
|
return {
|
|
22
22
|
lS: telemetry.getLastSynchronization(),
|
|
23
23
|
mL: telemetry.popLatencies(),
|
|
@@ -80,7 +80,7 @@ function telemetryCacheConfigAdapter(telemetry, settings) {
|
|
|
80
80
|
return {
|
|
81
81
|
isEmpty: function () { return false; },
|
|
82
82
|
clear: function () { },
|
|
83
|
-
|
|
83
|
+
pop: function () {
|
|
84
84
|
var urls = settings.urls, scheduler = settings.scheduler;
|
|
85
85
|
var isClientSide = settings.core.key !== undefined;
|
|
86
86
|
return (0, objectAssign_1.objectAssign)(getTelemetryConfigStats(settings.mode, settings.storage.type), {
|
package/esm/listeners/browser.js
CHANGED
|
@@ -74,7 +74,7 @@ var BrowserSignalListener = /** @class */ (function () {
|
|
|
74
74
|
BrowserSignalListener.prototype._flushData = function (url, cache, postService, fromCacheToPayload, extraMetadata) {
|
|
75
75
|
// if there is data in cache, send it to backend
|
|
76
76
|
if (!cache.isEmpty()) {
|
|
77
|
-
var dataPayload = fromCacheToPayload ? fromCacheToPayload(cache.
|
|
77
|
+
var dataPayload = fromCacheToPayload ? fromCacheToPayload(cache.pop()) : cache.pop();
|
|
78
78
|
if (!this._sendBeacon(url, dataPayload, extraMetadata)) {
|
|
79
79
|
postService(JSON.stringify(dataPayload)).catch(function () { }); // no-op just to catch a possible exception
|
|
80
80
|
}
|
|
@@ -10,7 +10,7 @@ export var codesWarn = codesError.concat([
|
|
|
10
10
|
[c.STREAMING_PARSING_ERROR_FAILS, c.LOG_PREFIX_SYNC_STREAMING + 'Error parsing SSE error notification: %s'],
|
|
11
11
|
[c.STREAMING_PARSING_MESSAGE_FAILS, c.LOG_PREFIX_SYNC_STREAMING + 'Error parsing SSE message notification: %s'],
|
|
12
12
|
[c.STREAMING_FALLBACK, c.LOG_PREFIX_SYNC_STREAMING + 'Falling back to polling mode. Reason: %s'],
|
|
13
|
-
[c.SUBMITTERS_PUSH_FAILS, c.LOG_PREFIX_SYNC_SUBMITTERS + '
|
|
13
|
+
[c.SUBMITTERS_PUSH_FAILS, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Dropping %s after retry. Reason: %s.'],
|
|
14
14
|
[c.SUBMITTERS_PUSH_RETRY, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Failed to push %s, keeping data to retry on next iteration. Reason: %s.'],
|
|
15
15
|
// client status
|
|
16
16
|
[c.CLIENT_NOT_READY, '%s: the SDK is not ready, results may be incorrect. Make sure to wait for SDK readiness before using this method.'],
|
|
@@ -32,10 +32,12 @@ var EventsCacheInMemory = /** @class */ (function () {
|
|
|
32
32
|
this.queueByteSize = 0;
|
|
33
33
|
};
|
|
34
34
|
/**
|
|
35
|
-
*
|
|
35
|
+
* Pop the collected data, used as payload for posting.
|
|
36
36
|
*/
|
|
37
|
-
EventsCacheInMemory.prototype.
|
|
38
|
-
|
|
37
|
+
EventsCacheInMemory.prototype.pop = function () {
|
|
38
|
+
var data = this.queue;
|
|
39
|
+
this.clear();
|
|
40
|
+
return data;
|
|
39
41
|
};
|
|
40
42
|
/**
|
|
41
43
|
* Check if the cache is empty.
|
|
@@ -18,14 +18,22 @@ var ImpressionCountsCacheInMemory = /** @class */ (function () {
|
|
|
18
18
|
this.cache[key] = currentAmount ? currentAmount + amount : amount;
|
|
19
19
|
};
|
|
20
20
|
/**
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
ImpressionCountsCacheInMemory.prototype.
|
|
24
|
-
|
|
21
|
+
* Pop the collected data, used as payload for posting.
|
|
22
|
+
*/
|
|
23
|
+
ImpressionCountsCacheInMemory.prototype.pop = function () {
|
|
24
|
+
var data = this.cache;
|
|
25
|
+
this.clear();
|
|
26
|
+
return data;
|
|
25
27
|
};
|
|
28
|
+
/**
|
|
29
|
+
* Clear the data stored on the cache.
|
|
30
|
+
*/
|
|
26
31
|
ImpressionCountsCacheInMemory.prototype.clear = function () {
|
|
27
32
|
this.cache = {};
|
|
28
33
|
};
|
|
34
|
+
/**
|
|
35
|
+
* Check if the cache is empty.
|
|
36
|
+
*/
|
|
29
37
|
ImpressionCountsCacheInMemory.prototype.isEmpty = function () {
|
|
30
38
|
return Object.keys(this.cache).length === 0;
|
|
31
39
|
};
|
|
@@ -30,10 +30,12 @@ var ImpressionsCacheInMemory = /** @class */ (function () {
|
|
|
30
30
|
this.queue = [];
|
|
31
31
|
};
|
|
32
32
|
/**
|
|
33
|
-
*
|
|
33
|
+
* Pop the collected data, used as payload for posting.
|
|
34
34
|
*/
|
|
35
|
-
ImpressionsCacheInMemory.prototype.
|
|
36
|
-
|
|
35
|
+
ImpressionsCacheInMemory.prototype.pop = function () {
|
|
36
|
+
var data = this.queue;
|
|
37
|
+
this.clear();
|
|
38
|
+
return data;
|
|
37
39
|
};
|
|
38
40
|
/**
|
|
39
41
|
* Check if the cache is empty.
|
|
@@ -7,26 +7,30 @@ export function submitterFactory(log, postClient, sourceCache, postRate, dataNam
|
|
|
7
7
|
) {
|
|
8
8
|
if (maxRetries === void 0) { maxRetries = 0; }
|
|
9
9
|
var retries = 0;
|
|
10
|
+
var data;
|
|
10
11
|
function postData() {
|
|
11
|
-
if (
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
if (!data) {
|
|
13
|
+
if (sourceCache.isEmpty())
|
|
14
|
+
return Promise.resolve();
|
|
15
|
+
// we clear the cache to track new items, while `data` is used for retries
|
|
16
|
+
data = sourceCache.pop();
|
|
17
|
+
}
|
|
14
18
|
// @ts-ignore
|
|
15
19
|
var dataCountMessage = typeof data.length === 'number' ? data.length + " " + dataName : dataName;
|
|
16
20
|
log[debugLogs ? 'debug' : 'info'](SUBMITTERS_PUSH, [dataCountMessage]);
|
|
17
21
|
var jsonPayload = JSON.stringify(fromCacheToPayload ? fromCacheToPayload(data) : data);
|
|
18
22
|
if (!maxRetries)
|
|
19
|
-
|
|
23
|
+
data = undefined;
|
|
20
24
|
return postClient(jsonPayload).then(function () {
|
|
21
25
|
retries = 0;
|
|
22
|
-
|
|
26
|
+
data = undefined;
|
|
23
27
|
}).catch(function (err) {
|
|
24
28
|
if (!maxRetries) {
|
|
25
29
|
log[debugLogs ? 'debug' : 'warn'](SUBMITTERS_PUSH_FAILS, [dataCountMessage, err]);
|
|
26
30
|
}
|
|
27
31
|
else if (retries === maxRetries) {
|
|
28
32
|
retries = 0;
|
|
29
|
-
|
|
33
|
+
data = undefined;
|
|
30
34
|
log[debugLogs ? 'debug' : 'warn'](SUBMITTERS_PUSH_FAILS, [dataCountMessage, err]);
|
|
31
35
|
}
|
|
32
36
|
else {
|
|
@@ -14,7 +14,7 @@ export function telemetryCacheStatsAdapter(telemetry, splits, segments) {
|
|
|
14
14
|
isEmpty: function () { return false; },
|
|
15
15
|
clear: function () { },
|
|
16
16
|
// @TODO consider moving inside telemetry cache for code size reduction
|
|
17
|
-
|
|
17
|
+
pop: function () {
|
|
18
18
|
return {
|
|
19
19
|
lS: telemetry.getLastSynchronization(),
|
|
20
20
|
mL: telemetry.popLatencies(),
|
|
@@ -75,7 +75,7 @@ export function telemetryCacheConfigAdapter(telemetry, settings) {
|
|
|
75
75
|
return {
|
|
76
76
|
isEmpty: function () { return false; },
|
|
77
77
|
clear: function () { },
|
|
78
|
-
|
|
78
|
+
pop: function () {
|
|
79
79
|
var urls = settings.urls, scheduler = settings.scheduler;
|
|
80
80
|
var isClientSide = settings.core.key !== undefined;
|
|
81
81
|
return objectAssign(getTelemetryConfigStats(settings.mode, settings.storage.type), {
|
package/package.json
CHANGED
package/src/listeners/browser.ts
CHANGED
|
@@ -92,7 +92,7 @@ export class BrowserSignalListener implements ISignalListener {
|
|
|
92
92
|
private _flushData<TState>(url: string, cache: IRecorderCacheProducerSync<TState>, postService: (body: string) => Promise<IResponse>, fromCacheToPayload?: (cacheData: TState) => any, extraMetadata?: {}) {
|
|
93
93
|
// if there is data in cache, send it to backend
|
|
94
94
|
if (!cache.isEmpty()) {
|
|
95
|
-
const dataPayload = fromCacheToPayload ? fromCacheToPayload(cache.
|
|
95
|
+
const dataPayload = fromCacheToPayload ? fromCacheToPayload(cache.pop()) : cache.pop();
|
|
96
96
|
if (!this._sendBeacon(url, dataPayload, extraMetadata)) {
|
|
97
97
|
postService(JSON.stringify(dataPayload)).catch(() => { }); // no-op just to catch a possible exception
|
|
98
98
|
}
|
|
@@ -11,7 +11,7 @@ export const codesWarn: [number, string][] = codesError.concat([
|
|
|
11
11
|
[c.STREAMING_PARSING_ERROR_FAILS, c.LOG_PREFIX_SYNC_STREAMING + 'Error parsing SSE error notification: %s'],
|
|
12
12
|
[c.STREAMING_PARSING_MESSAGE_FAILS, c.LOG_PREFIX_SYNC_STREAMING + 'Error parsing SSE message notification: %s'],
|
|
13
13
|
[c.STREAMING_FALLBACK, c.LOG_PREFIX_SYNC_STREAMING + 'Falling back to polling mode. Reason: %s'],
|
|
14
|
-
[c.SUBMITTERS_PUSH_FAILS, c.LOG_PREFIX_SYNC_SUBMITTERS + '
|
|
14
|
+
[c.SUBMITTERS_PUSH_FAILS, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Dropping %s after retry. Reason: %s.'],
|
|
15
15
|
[c.SUBMITTERS_PUSH_RETRY, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Failed to push %s, keeping data to retry on next iteration. Reason: %s.'],
|
|
16
16
|
// client status
|
|
17
17
|
[c.CLIENT_NOT_READY, '%s: the SDK is not ready, results may be incorrect. Make sure to wait for SDK readiness before using this method.'],
|
|
@@ -46,10 +46,12 @@ export class EventsCacheInMemory implements IEventsCacheSync {
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
/**
|
|
49
|
-
*
|
|
49
|
+
* Pop the collected data, used as payload for posting.
|
|
50
50
|
*/
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
pop() {
|
|
52
|
+
const data = this.queue;
|
|
53
|
+
this.clear();
|
|
54
|
+
return data;
|
|
53
55
|
}
|
|
54
56
|
|
|
55
57
|
/**
|
|
@@ -20,17 +20,27 @@ export class ImpressionCountsCacheInMemory implements IImpressionCountsCacheSync
|
|
|
20
20
|
this.cache[key] = currentAmount ? currentAmount + amount : amount;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
|
|
24
|
+
|
|
23
25
|
/**
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
* Pop the collected data, used as payload for posting.
|
|
27
|
+
*/
|
|
28
|
+
pop() {
|
|
29
|
+
const data = this.cache;
|
|
30
|
+
this.clear();
|
|
31
|
+
return data;
|
|
28
32
|
}
|
|
29
33
|
|
|
34
|
+
/**
|
|
35
|
+
* Clear the data stored on the cache.
|
|
36
|
+
*/
|
|
30
37
|
clear() {
|
|
31
38
|
this.cache = {};
|
|
32
39
|
}
|
|
33
40
|
|
|
41
|
+
/**
|
|
42
|
+
* Check if the cache is empty.
|
|
43
|
+
*/
|
|
34
44
|
isEmpty() {
|
|
35
45
|
return Object.keys(this.cache).length === 0;
|
|
36
46
|
}
|
|
@@ -41,10 +41,12 @@ export class ImpressionsCacheInMemory implements IImpressionsCacheSync {
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
/**
|
|
44
|
-
*
|
|
44
|
+
* Pop the collected data, used as payload for posting.
|
|
45
45
|
*/
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
pop() {
|
|
47
|
+
const data = this.queue;
|
|
48
|
+
this.clear();
|
|
49
|
+
return data;
|
|
48
50
|
}
|
|
49
51
|
|
|
50
52
|
/**
|
package/src/storages/types.ts
CHANGED
|
@@ -301,8 +301,8 @@ export interface IRecorderCacheProducerSync<T> {
|
|
|
301
301
|
isEmpty(): boolean
|
|
302
302
|
/* Clears cache data */
|
|
303
303
|
clear(): void
|
|
304
|
-
/*
|
|
305
|
-
|
|
304
|
+
/* Pops cache data */
|
|
305
|
+
pop(): T
|
|
306
306
|
}
|
|
307
307
|
|
|
308
308
|
|
|
@@ -352,8 +352,7 @@ export interface IImpressionCountsCacheSync extends IRecorderCacheProducerSync<R
|
|
|
352
352
|
|
|
353
353
|
// Used by impressions count submitter in standalone and producer mode
|
|
354
354
|
isEmpty(): boolean // check if cache is empty. Return true if the cache was just created or cleared.
|
|
355
|
-
|
|
356
|
-
state(): Record<string, number> // get cache data
|
|
355
|
+
pop(): Record<string, number> // pop cache data
|
|
357
356
|
}
|
|
358
357
|
|
|
359
358
|
|
|
@@ -20,27 +20,31 @@ export function submitterFactory<TState>(
|
|
|
20
20
|
): ISyncTask<[], void> {
|
|
21
21
|
|
|
22
22
|
let retries = 0;
|
|
23
|
+
let data: TState | undefined;
|
|
23
24
|
|
|
24
25
|
function postData(): Promise<any> {
|
|
25
|
-
if (
|
|
26
|
+
if (!data) {
|
|
27
|
+
if (sourceCache.isEmpty()) return Promise.resolve();
|
|
28
|
+
// we clear the cache to track new items, while `data` is used for retries
|
|
29
|
+
data = sourceCache.pop();
|
|
30
|
+
}
|
|
26
31
|
|
|
27
|
-
const data = sourceCache.state();
|
|
28
32
|
// @ts-ignore
|
|
29
33
|
const dataCountMessage = typeof data.length === 'number' ? `${data.length} ${dataName}` : dataName;
|
|
30
34
|
log[debugLogs ? 'debug' : 'info'](SUBMITTERS_PUSH, [dataCountMessage]);
|
|
31
35
|
|
|
32
36
|
const jsonPayload = JSON.stringify(fromCacheToPayload ? fromCacheToPayload(data) : data);
|
|
33
|
-
if (!maxRetries)
|
|
37
|
+
if (!maxRetries) data = undefined;
|
|
34
38
|
|
|
35
39
|
return postClient(jsonPayload).then(() => {
|
|
36
40
|
retries = 0;
|
|
37
|
-
|
|
41
|
+
data = undefined;
|
|
38
42
|
}).catch(err => {
|
|
39
43
|
if (!maxRetries) {
|
|
40
44
|
log[debugLogs ? 'debug' : 'warn'](SUBMITTERS_PUSH_FAILS, [dataCountMessage, err]);
|
|
41
45
|
} else if (retries === maxRetries) {
|
|
42
46
|
retries = 0;
|
|
43
|
-
|
|
47
|
+
data = undefined;
|
|
44
48
|
log[debugLogs ? 'debug' : 'warn'](SUBMITTERS_PUSH_FAILS, [dataCountMessage, err]);
|
|
45
49
|
} else {
|
|
46
50
|
retries++;
|
|
@@ -19,7 +19,7 @@ export function telemetryCacheStatsAdapter(telemetry: ITelemetryCacheSync, split
|
|
|
19
19
|
clear() { }, // No-op
|
|
20
20
|
|
|
21
21
|
// @TODO consider moving inside telemetry cache for code size reduction
|
|
22
|
-
|
|
22
|
+
pop(): TelemetryUsageStatsPayload {
|
|
23
23
|
return {
|
|
24
24
|
lS: telemetry.getLastSynchronization(),
|
|
25
25
|
mL: telemetry.popLatencies(),
|
|
@@ -88,7 +88,7 @@ export function telemetryCacheConfigAdapter(telemetry: ITelemetryCacheSync, sett
|
|
|
88
88
|
isEmpty() { return false; },
|
|
89
89
|
clear() { },
|
|
90
90
|
|
|
91
|
-
|
|
91
|
+
pop(): TelemetryConfigStatsPayload {
|
|
92
92
|
const { urls, scheduler } = settings;
|
|
93
93
|
const isClientSide = settings.core.key !== undefined;
|
|
94
94
|
|
|
@@ -21,9 +21,9 @@ export declare class EventsCacheInMemory implements IEventsCacheSync {
|
|
|
21
21
|
*/
|
|
22
22
|
clear(): void;
|
|
23
23
|
/**
|
|
24
|
-
*
|
|
24
|
+
* Pop the collected data, used as payload for posting.
|
|
25
25
|
*/
|
|
26
|
-
|
|
26
|
+
pop(): SplitIO.EventData[];
|
|
27
27
|
/**
|
|
28
28
|
* Check if the cache is empty.
|
|
29
29
|
*/
|
|
@@ -10,9 +10,15 @@ export declare class ImpressionCountsCacheInMemory implements IImpressionCountsC
|
|
|
10
10
|
*/
|
|
11
11
|
track(featureName: string, timeFrame: number, amount: number): void;
|
|
12
12
|
/**
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
* Pop the collected data, used as payload for posting.
|
|
14
|
+
*/
|
|
15
|
+
pop(): Record<string, number>;
|
|
16
|
+
/**
|
|
17
|
+
* Clear the data stored on the cache.
|
|
18
|
+
*/
|
|
16
19
|
clear(): void;
|
|
20
|
+
/**
|
|
21
|
+
* Check if the cache is empty.
|
|
22
|
+
*/
|
|
17
23
|
isEmpty(): boolean;
|
|
18
24
|
}
|
|
@@ -20,9 +20,9 @@ export declare class ImpressionsCacheInMemory implements IImpressionsCacheSync {
|
|
|
20
20
|
*/
|
|
21
21
|
clear(): void;
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
23
|
+
* Pop the collected data, used as payload for posting.
|
|
24
24
|
*/
|
|
25
|
-
|
|
25
|
+
pop(): ImpressionDTO[];
|
|
26
26
|
/**
|
|
27
27
|
* Check if the cache is empty.
|
|
28
28
|
*/
|
|
@@ -266,7 +266,7 @@ export interface IEventsCacheBase {
|
|
|
266
266
|
export interface IRecorderCacheProducerSync<T> {
|
|
267
267
|
isEmpty(): boolean;
|
|
268
268
|
clear(): void;
|
|
269
|
-
|
|
269
|
+
pop(): T;
|
|
270
270
|
}
|
|
271
271
|
export interface IImpressionsCacheSync extends IImpressionsCacheBase, IRecorderCacheProducerSync<ImpressionDTO[]> {
|
|
272
272
|
track(data: ImpressionDTO[]): void;
|
|
@@ -295,8 +295,7 @@ export interface IEventsCacheAsync extends IEventsCacheBase, IRecorderCacheProdu
|
|
|
295
295
|
export interface IImpressionCountsCacheSync extends IRecorderCacheProducerSync<Record<string, number>> {
|
|
296
296
|
track(featureName: string, timeFrame: number, amount: number): void;
|
|
297
297
|
isEmpty(): boolean;
|
|
298
|
-
|
|
299
|
-
state(): Record<string, number>;
|
|
298
|
+
pop(): Record<string, number>;
|
|
300
299
|
}
|
|
301
300
|
/**
|
|
302
301
|
* Telemetry storage interface for standalone and partial consumer modes.
|
|
@@ -8,7 +8,7 @@ import { ISdkFactoryContextSync } from '../../sdkFactory/types';
|
|
|
8
8
|
export declare function telemetryCacheStatsAdapter(telemetry: ITelemetryCacheSync, splits: ISplitsCacheSync, segments: ISegmentsCacheSync): {
|
|
9
9
|
isEmpty(): boolean;
|
|
10
10
|
clear(): void;
|
|
11
|
-
|
|
11
|
+
pop(): TelemetryUsageStatsPayload;
|
|
12
12
|
};
|
|
13
13
|
export declare function getTelemetryConfigStats(mode: SDKMode, storageType: string): TelemetryConfigStats;
|
|
14
14
|
/**
|
|
@@ -17,7 +17,7 @@ export declare function getTelemetryConfigStats(mode: SDKMode, storageType: stri
|
|
|
17
17
|
export declare function telemetryCacheConfigAdapter(telemetry: ITelemetryCacheSync, settings: ISettings): {
|
|
18
18
|
isEmpty(): boolean;
|
|
19
19
|
clear(): void;
|
|
20
|
-
|
|
20
|
+
pop(): TelemetryConfigStatsPayload;
|
|
21
21
|
};
|
|
22
22
|
/**
|
|
23
23
|
* Submitter that periodically posts telemetry data
|