@splitsoftware/splitio-commons 1.3.2-rc.3 → 1.3.2-rc.6
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 +5 -0
- package/cjs/listeners/browser.js +6 -1
- package/cjs/storages/KeyBuilderSS.js +9 -5
- package/cjs/storages/inRedis/RedisAdapter.js +1 -1
- package/cjs/storages/inRedis/TelemetryCacheInRedis.js +7 -0
- package/cjs/storages/inRedis/index.js +4 -1
- package/cjs/storages/pluggable/index.js +2 -1
- package/cjs/sync/submitters/telemetrySubmitter.js +31 -17
- package/cjs/trackers/telemetryTracker.js +2 -2
- package/cjs/utils/timeTracker/now/browser.js +1 -1
- package/cjs/utils/timeTracker/now/node.js +1 -2
- package/esm/listeners/browser.js +6 -1
- package/esm/storages/KeyBuilderSS.js +9 -5
- package/esm/storages/inRedis/RedisAdapter.js +1 -1
- package/esm/storages/inRedis/TelemetryCacheInRedis.js +7 -0
- package/esm/storages/inRedis/index.js +4 -1
- package/esm/storages/pluggable/index.js +2 -1
- package/esm/sync/submitters/telemetrySubmitter.js +30 -17
- package/esm/trackers/telemetryTracker.js +2 -2
- package/esm/utils/timeTracker/now/browser.js +1 -1
- package/esm/utils/timeTracker/now/node.js +1 -2
- package/package.json +1 -1
- package/src/listeners/browser.ts +6 -1
- package/src/sdkFactory/types.ts +16 -2
- package/src/storages/KeyBuilderSS.ts +12 -6
- package/src/storages/inRedis/RedisAdapter.ts +1 -1
- package/src/storages/inRedis/TelemetryCacheInRedis.ts +7 -0
- package/src/storages/inRedis/index.ts +5 -1
- package/src/storages/pluggable/index.ts +2 -1
- package/src/sync/submitters/telemetrySubmitter.ts +33 -18
- package/src/sync/submitters/types.ts +13 -7
- package/src/trackers/telemetryTracker.ts +2 -2
- package/src/utils/murmur3/utfx.ts +1 -2
- package/src/utils/timeTracker/now/browser.ts +1 -1
- package/src/utils/timeTracker/now/node.ts +1 -2
- package/types/sdkFactory/types.d.ts +16 -2
- package/types/storages/KeyBuilderSS.d.ts +3 -2
- package/types/storages/inRedis/TelemetryCacheInRedis.d.ts +1 -0
- package/types/sync/submitters/telemetrySubmitter.d.ts +3 -2
- package/types/sync/submitters/types.d.ts +10 -6
- package/types/utils/timeTracker/index.d.ts +1 -70
- package/cjs/utils/timeTracker/index.js +0 -197
- package/esm/utils/timeTracker/index.js +0 -194
- package/src/utils/timeTracker/index.ts +0 -226
|
@@ -1,197 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var _a;
|
|
3
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.TrackerAPI = void 0;
|
|
5
|
-
var lang_1 = require("../lang");
|
|
6
|
-
var timer_1 = require("./timer");
|
|
7
|
-
var thenable_1 = require("../promise/thenable");
|
|
8
|
-
// Map we will use for storing timers data
|
|
9
|
-
var timers = {};
|
|
10
|
-
// Tasks constants
|
|
11
|
-
var CONSTANTS = {
|
|
12
|
-
SDK_READY: 'Getting ready - Split SDK',
|
|
13
|
-
SDK_GET_TREATMENT: 'SDK - Get Treatment',
|
|
14
|
-
SDK_GET_TREATMENTS: 'SDK - Get Treatments',
|
|
15
|
-
SDK_GET_TREATMENT_WITH_CONFIG: 'SDK - Get Treatment with config',
|
|
16
|
-
SDK_GET_TREATMENTS_WITH_CONFIG: 'SDK - Get Treatments with config',
|
|
17
|
-
SPLITS_READY: 'Getting ready - Splits',
|
|
18
|
-
SEGMENTS_READY: 'Getting ready - Segments',
|
|
19
|
-
METRICS_PUSH: 'Pushing - Metrics',
|
|
20
|
-
IMPRESSIONS_PUSH: 'Pushing - Impressions',
|
|
21
|
-
EVENTS_PUSH: 'Pushing - Events',
|
|
22
|
-
MY_SEGMENTS_FETCH: 'Fetching - My Segments',
|
|
23
|
-
SEGMENTS_FETCH: 'Fetching - Segments',
|
|
24
|
-
SPLITS_FETCH: 'Fetching - Splits'
|
|
25
|
-
};
|
|
26
|
-
// Tasks callbacks, if any
|
|
27
|
-
var CALLBACKS = (_a = {},
|
|
28
|
-
_a[CONSTANTS.SDK_READY] = {
|
|
29
|
-
collector: 'client',
|
|
30
|
-
method: 'ready'
|
|
31
|
-
},
|
|
32
|
-
_a[CONSTANTS.SDK_GET_TREATMENT] = {
|
|
33
|
-
collector: 'client',
|
|
34
|
-
method: 'getTreatment'
|
|
35
|
-
},
|
|
36
|
-
_a[CONSTANTS.SDK_GET_TREATMENTS] = {
|
|
37
|
-
collector: 'client',
|
|
38
|
-
method: 'getTreatments'
|
|
39
|
-
},
|
|
40
|
-
_a[CONSTANTS.SDK_GET_TREATMENT_WITH_CONFIG] = {
|
|
41
|
-
collector: 'client',
|
|
42
|
-
method: 'getTreatmentWithConfig'
|
|
43
|
-
},
|
|
44
|
-
_a[CONSTANTS.SDK_GET_TREATMENTS_WITH_CONFIG] = {
|
|
45
|
-
collector: 'client',
|
|
46
|
-
method: 'getTreatmentsWithConfig'
|
|
47
|
-
},
|
|
48
|
-
_a[CONSTANTS.MY_SEGMENTS_FETCH] = {
|
|
49
|
-
collector: 'mySegments',
|
|
50
|
-
method: 'latency'
|
|
51
|
-
},
|
|
52
|
-
_a[CONSTANTS.SEGMENTS_FETCH] = {
|
|
53
|
-
collector: 'segmentChanges',
|
|
54
|
-
method: 'latency'
|
|
55
|
-
},
|
|
56
|
-
_a[CONSTANTS.SPLITS_FETCH] = {
|
|
57
|
-
collector: 'splitChanges',
|
|
58
|
-
method: 'latency'
|
|
59
|
-
},
|
|
60
|
-
_a);
|
|
61
|
-
/**
|
|
62
|
-
* Generates the timer keys using the task name and a modifier, if any.
|
|
63
|
-
* @param {string} task - The task name
|
|
64
|
-
* @param {number | string} modifier - (optional) The modifier, if any.
|
|
65
|
-
* @return {string} The generated timer key
|
|
66
|
-
*/
|
|
67
|
-
function generateTimerKey(task, modifier) { return modifier ? task + modifier : task; }
|
|
68
|
-
/**
|
|
69
|
-
* Given the collectors map, it returns the specific collector for a given task.
|
|
70
|
-
*
|
|
71
|
-
* @param {string} task - The task name
|
|
72
|
-
* @param {Object} collectors - The collectors map
|
|
73
|
-
*/
|
|
74
|
-
function getCollectorForTask(task, collectors) {
|
|
75
|
-
var callbackData = CALLBACKS[task];
|
|
76
|
-
if (callbackData && collectors)
|
|
77
|
-
return collectors[callbackData.collector];
|
|
78
|
-
return false;
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* Given a collector and a task, returns the callback function that should be called when we stop the timer.
|
|
82
|
-
*
|
|
83
|
-
* @param {string} task - The task name
|
|
84
|
-
* @param {Object} collector - The collector object for the task
|
|
85
|
-
*/
|
|
86
|
-
function getCallbackForTask(task, collector) {
|
|
87
|
-
var callbackData = CALLBACKS[task];
|
|
88
|
-
if (callbackData && collector)
|
|
89
|
-
return collector[callbackData.method];
|
|
90
|
-
return false;
|
|
91
|
-
}
|
|
92
|
-
// Our "time tracker" API
|
|
93
|
-
exports.TrackerAPI = {
|
|
94
|
-
/**
|
|
95
|
-
* "Private" method, used to attach count/countException and stop callbacks to a promise.
|
|
96
|
-
*
|
|
97
|
-
* @param {ILogger} log - Logger.
|
|
98
|
-
* @param {Promise} promise - The promise we want to attach the callbacks.
|
|
99
|
-
* @param {string} task - The name of the task.
|
|
100
|
-
* @param {number | string} modifier - (optional) The modifier for the task, if any.
|
|
101
|
-
*/
|
|
102
|
-
__attachToPromise: function (log, promise, task, collector, modifier) {
|
|
103
|
-
var _this = this;
|
|
104
|
-
return promise.then(function (resp) {
|
|
105
|
-
_this.stop(log, task, modifier);
|
|
106
|
-
if (collector && collector.count)
|
|
107
|
-
collector.count(resp.status);
|
|
108
|
-
return resp;
|
|
109
|
-
})
|
|
110
|
-
.catch(function (err) {
|
|
111
|
-
_this.stop(log, task, modifier);
|
|
112
|
-
if (collector && collector.countException)
|
|
113
|
-
collector.countException();
|
|
114
|
-
throw err;
|
|
115
|
-
});
|
|
116
|
-
},
|
|
117
|
-
/**
|
|
118
|
-
* Starts tracking the time for a given task. All tasks tracked are considered "unique" because
|
|
119
|
-
* there may be multiple SDK instances tracking a "generic" task, making any task non-generic.
|
|
120
|
-
*
|
|
121
|
-
* @param {ILogger} log - Logger.
|
|
122
|
-
* @param {string} task - The task we are starting.
|
|
123
|
-
* @param {Object} collectors - The collectors map.
|
|
124
|
-
* @param {Promise} promise - (optional) The promise we are tracking.
|
|
125
|
-
* @return {Function | Promise} The stop function for this specific task or the promise received with the callbacks registered.
|
|
126
|
-
*/
|
|
127
|
-
start: function (log, task, collectors, promise, now) {
|
|
128
|
-
if (now === void 0) { now = Date.now; }
|
|
129
|
-
var taskUniqueId = (0, lang_1.uniqueId)();
|
|
130
|
-
var taskCollector = getCollectorForTask(task, collectors);
|
|
131
|
-
var result;
|
|
132
|
-
// If we are registering a promise with this task, we should count the status and the exceptions as well
|
|
133
|
-
// as stopping the task when the promise resolves. Then return the promise
|
|
134
|
-
if ((0, thenable_1.thenable)(promise)) {
|
|
135
|
-
result = this.__attachToPromise(log, promise, task, taskCollector, taskUniqueId);
|
|
136
|
-
}
|
|
137
|
-
else {
|
|
138
|
-
// If not, we return the stop function, as it will be stopped manually.
|
|
139
|
-
result = this.stop.bind(this, log, task, taskUniqueId);
|
|
140
|
-
if (CALLBACKS[task] && !taskCollector) {
|
|
141
|
-
// and provide a way for a defered setup of the collector, if needed.
|
|
142
|
-
// @ts-expect-error
|
|
143
|
-
result.setCollectorForTask = this.setCollectorForTask.bind(this, task, taskUniqueId);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
// We start the timer, with an uniqueId attached to it's name, and save tracking info for this task.
|
|
147
|
-
var trackingKey = generateTimerKey(task, taskUniqueId);
|
|
148
|
-
var cb = getCallbackForTask(task, taskCollector);
|
|
149
|
-
timers[trackingKey] = {
|
|
150
|
-
cb: cb,
|
|
151
|
-
timer: (0, timer_1.timer)(now)
|
|
152
|
-
};
|
|
153
|
-
return result;
|
|
154
|
-
},
|
|
155
|
-
/**
|
|
156
|
-
* Setup the collector for a task that reports metrics.
|
|
157
|
-
*
|
|
158
|
-
* @param {string} task - The task name
|
|
159
|
-
* @param {number | string} taskUniqueId - The unique identifier for this task
|
|
160
|
-
* @param {Object} collectors - The collectors map.
|
|
161
|
-
*/
|
|
162
|
-
setCollectorForTask: function (task, taskUniqueId, collectors) {
|
|
163
|
-
var taskCollector = getCollectorForTask(task, collectors);
|
|
164
|
-
if (taskCollector) {
|
|
165
|
-
var trackingKey = generateTimerKey(task, taskUniqueId);
|
|
166
|
-
timers[trackingKey].cb = getCallbackForTask(task, taskCollector);
|
|
167
|
-
}
|
|
168
|
-
},
|
|
169
|
-
/**
|
|
170
|
-
* Stops the tracking of a given task.
|
|
171
|
-
*
|
|
172
|
-
* @param {ILogger} log - Logger.
|
|
173
|
-
* @param {string} task - The task we are starting.
|
|
174
|
-
* @param {number | string} modifier - (optional) The modifier for that specific task.
|
|
175
|
-
*/
|
|
176
|
-
stop: function (log, task, modifier) {
|
|
177
|
-
var timerName = generateTimerKey(task, modifier);
|
|
178
|
-
var timerData = timers[timerName];
|
|
179
|
-
if (timerData) {
|
|
180
|
-
// Stop the timer and round result for readability.
|
|
181
|
-
var et = timerData.timer();
|
|
182
|
-
log.debug("[TIME TRACKER]: [" + task + "] took " + et + "ms to finish.");
|
|
183
|
-
// Check if we have a tracker callback.
|
|
184
|
-
if (timerData.cb) {
|
|
185
|
-
// If we have a callback, we call it with the elapsed time of the task and then delete the reference.
|
|
186
|
-
timerData.cb(et);
|
|
187
|
-
}
|
|
188
|
-
// Remove the task tracking reference.
|
|
189
|
-
delete timers[timerName];
|
|
190
|
-
return et;
|
|
191
|
-
}
|
|
192
|
-
},
|
|
193
|
-
/**
|
|
194
|
-
* The constants shortcut for the task names.
|
|
195
|
-
*/
|
|
196
|
-
TaskNames: CONSTANTS
|
|
197
|
-
};
|
|
@@ -1,194 +0,0 @@
|
|
|
1
|
-
var _a;
|
|
2
|
-
import { uniqueId } from '../lang';
|
|
3
|
-
import { timer } from './timer';
|
|
4
|
-
import { thenable } from '../promise/thenable';
|
|
5
|
-
// Map we will use for storing timers data
|
|
6
|
-
var timers = {};
|
|
7
|
-
// Tasks constants
|
|
8
|
-
var CONSTANTS = {
|
|
9
|
-
SDK_READY: 'Getting ready - Split SDK',
|
|
10
|
-
SDK_GET_TREATMENT: 'SDK - Get Treatment',
|
|
11
|
-
SDK_GET_TREATMENTS: 'SDK - Get Treatments',
|
|
12
|
-
SDK_GET_TREATMENT_WITH_CONFIG: 'SDK - Get Treatment with config',
|
|
13
|
-
SDK_GET_TREATMENTS_WITH_CONFIG: 'SDK - Get Treatments with config',
|
|
14
|
-
SPLITS_READY: 'Getting ready - Splits',
|
|
15
|
-
SEGMENTS_READY: 'Getting ready - Segments',
|
|
16
|
-
METRICS_PUSH: 'Pushing - Metrics',
|
|
17
|
-
IMPRESSIONS_PUSH: 'Pushing - Impressions',
|
|
18
|
-
EVENTS_PUSH: 'Pushing - Events',
|
|
19
|
-
MY_SEGMENTS_FETCH: 'Fetching - My Segments',
|
|
20
|
-
SEGMENTS_FETCH: 'Fetching - Segments',
|
|
21
|
-
SPLITS_FETCH: 'Fetching - Splits'
|
|
22
|
-
};
|
|
23
|
-
// Tasks callbacks, if any
|
|
24
|
-
var CALLBACKS = (_a = {},
|
|
25
|
-
_a[CONSTANTS.SDK_READY] = {
|
|
26
|
-
collector: 'client',
|
|
27
|
-
method: 'ready'
|
|
28
|
-
},
|
|
29
|
-
_a[CONSTANTS.SDK_GET_TREATMENT] = {
|
|
30
|
-
collector: 'client',
|
|
31
|
-
method: 'getTreatment'
|
|
32
|
-
},
|
|
33
|
-
_a[CONSTANTS.SDK_GET_TREATMENTS] = {
|
|
34
|
-
collector: 'client',
|
|
35
|
-
method: 'getTreatments'
|
|
36
|
-
},
|
|
37
|
-
_a[CONSTANTS.SDK_GET_TREATMENT_WITH_CONFIG] = {
|
|
38
|
-
collector: 'client',
|
|
39
|
-
method: 'getTreatmentWithConfig'
|
|
40
|
-
},
|
|
41
|
-
_a[CONSTANTS.SDK_GET_TREATMENTS_WITH_CONFIG] = {
|
|
42
|
-
collector: 'client',
|
|
43
|
-
method: 'getTreatmentsWithConfig'
|
|
44
|
-
},
|
|
45
|
-
_a[CONSTANTS.MY_SEGMENTS_FETCH] = {
|
|
46
|
-
collector: 'mySegments',
|
|
47
|
-
method: 'latency'
|
|
48
|
-
},
|
|
49
|
-
_a[CONSTANTS.SEGMENTS_FETCH] = {
|
|
50
|
-
collector: 'segmentChanges',
|
|
51
|
-
method: 'latency'
|
|
52
|
-
},
|
|
53
|
-
_a[CONSTANTS.SPLITS_FETCH] = {
|
|
54
|
-
collector: 'splitChanges',
|
|
55
|
-
method: 'latency'
|
|
56
|
-
},
|
|
57
|
-
_a);
|
|
58
|
-
/**
|
|
59
|
-
* Generates the timer keys using the task name and a modifier, if any.
|
|
60
|
-
* @param {string} task - The task name
|
|
61
|
-
* @param {number | string} modifier - (optional) The modifier, if any.
|
|
62
|
-
* @return {string} The generated timer key
|
|
63
|
-
*/
|
|
64
|
-
function generateTimerKey(task, modifier) { return modifier ? task + modifier : task; }
|
|
65
|
-
/**
|
|
66
|
-
* Given the collectors map, it returns the specific collector for a given task.
|
|
67
|
-
*
|
|
68
|
-
* @param {string} task - The task name
|
|
69
|
-
* @param {Object} collectors - The collectors map
|
|
70
|
-
*/
|
|
71
|
-
function getCollectorForTask(task, collectors) {
|
|
72
|
-
var callbackData = CALLBACKS[task];
|
|
73
|
-
if (callbackData && collectors)
|
|
74
|
-
return collectors[callbackData.collector];
|
|
75
|
-
return false;
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Given a collector and a task, returns the callback function that should be called when we stop the timer.
|
|
79
|
-
*
|
|
80
|
-
* @param {string} task - The task name
|
|
81
|
-
* @param {Object} collector - The collector object for the task
|
|
82
|
-
*/
|
|
83
|
-
function getCallbackForTask(task, collector) {
|
|
84
|
-
var callbackData = CALLBACKS[task];
|
|
85
|
-
if (callbackData && collector)
|
|
86
|
-
return collector[callbackData.method];
|
|
87
|
-
return false;
|
|
88
|
-
}
|
|
89
|
-
// Our "time tracker" API
|
|
90
|
-
export var TrackerAPI = {
|
|
91
|
-
/**
|
|
92
|
-
* "Private" method, used to attach count/countException and stop callbacks to a promise.
|
|
93
|
-
*
|
|
94
|
-
* @param {ILogger} log - Logger.
|
|
95
|
-
* @param {Promise} promise - The promise we want to attach the callbacks.
|
|
96
|
-
* @param {string} task - The name of the task.
|
|
97
|
-
* @param {number | string} modifier - (optional) The modifier for the task, if any.
|
|
98
|
-
*/
|
|
99
|
-
__attachToPromise: function (log, promise, task, collector, modifier) {
|
|
100
|
-
var _this = this;
|
|
101
|
-
return promise.then(function (resp) {
|
|
102
|
-
_this.stop(log, task, modifier);
|
|
103
|
-
if (collector && collector.count)
|
|
104
|
-
collector.count(resp.status);
|
|
105
|
-
return resp;
|
|
106
|
-
})
|
|
107
|
-
.catch(function (err) {
|
|
108
|
-
_this.stop(log, task, modifier);
|
|
109
|
-
if (collector && collector.countException)
|
|
110
|
-
collector.countException();
|
|
111
|
-
throw err;
|
|
112
|
-
});
|
|
113
|
-
},
|
|
114
|
-
/**
|
|
115
|
-
* Starts tracking the time for a given task. All tasks tracked are considered "unique" because
|
|
116
|
-
* there may be multiple SDK instances tracking a "generic" task, making any task non-generic.
|
|
117
|
-
*
|
|
118
|
-
* @param {ILogger} log - Logger.
|
|
119
|
-
* @param {string} task - The task we are starting.
|
|
120
|
-
* @param {Object} collectors - The collectors map.
|
|
121
|
-
* @param {Promise} promise - (optional) The promise we are tracking.
|
|
122
|
-
* @return {Function | Promise} The stop function for this specific task or the promise received with the callbacks registered.
|
|
123
|
-
*/
|
|
124
|
-
start: function (log, task, collectors, promise, now) {
|
|
125
|
-
if (now === void 0) { now = Date.now; }
|
|
126
|
-
var taskUniqueId = uniqueId();
|
|
127
|
-
var taskCollector = getCollectorForTask(task, collectors);
|
|
128
|
-
var result;
|
|
129
|
-
// If we are registering a promise with this task, we should count the status and the exceptions as well
|
|
130
|
-
// as stopping the task when the promise resolves. Then return the promise
|
|
131
|
-
if (thenable(promise)) {
|
|
132
|
-
result = this.__attachToPromise(log, promise, task, taskCollector, taskUniqueId);
|
|
133
|
-
}
|
|
134
|
-
else {
|
|
135
|
-
// If not, we return the stop function, as it will be stopped manually.
|
|
136
|
-
result = this.stop.bind(this, log, task, taskUniqueId);
|
|
137
|
-
if (CALLBACKS[task] && !taskCollector) {
|
|
138
|
-
// and provide a way for a defered setup of the collector, if needed.
|
|
139
|
-
// @ts-expect-error
|
|
140
|
-
result.setCollectorForTask = this.setCollectorForTask.bind(this, task, taskUniqueId);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
// We start the timer, with an uniqueId attached to it's name, and save tracking info for this task.
|
|
144
|
-
var trackingKey = generateTimerKey(task, taskUniqueId);
|
|
145
|
-
var cb = getCallbackForTask(task, taskCollector);
|
|
146
|
-
timers[trackingKey] = {
|
|
147
|
-
cb: cb,
|
|
148
|
-
timer: timer(now)
|
|
149
|
-
};
|
|
150
|
-
return result;
|
|
151
|
-
},
|
|
152
|
-
/**
|
|
153
|
-
* Setup the collector for a task that reports metrics.
|
|
154
|
-
*
|
|
155
|
-
* @param {string} task - The task name
|
|
156
|
-
* @param {number | string} taskUniqueId - The unique identifier for this task
|
|
157
|
-
* @param {Object} collectors - The collectors map.
|
|
158
|
-
*/
|
|
159
|
-
setCollectorForTask: function (task, taskUniqueId, collectors) {
|
|
160
|
-
var taskCollector = getCollectorForTask(task, collectors);
|
|
161
|
-
if (taskCollector) {
|
|
162
|
-
var trackingKey = generateTimerKey(task, taskUniqueId);
|
|
163
|
-
timers[trackingKey].cb = getCallbackForTask(task, taskCollector);
|
|
164
|
-
}
|
|
165
|
-
},
|
|
166
|
-
/**
|
|
167
|
-
* Stops the tracking of a given task.
|
|
168
|
-
*
|
|
169
|
-
* @param {ILogger} log - Logger.
|
|
170
|
-
* @param {string} task - The task we are starting.
|
|
171
|
-
* @param {number | string} modifier - (optional) The modifier for that specific task.
|
|
172
|
-
*/
|
|
173
|
-
stop: function (log, task, modifier) {
|
|
174
|
-
var timerName = generateTimerKey(task, modifier);
|
|
175
|
-
var timerData = timers[timerName];
|
|
176
|
-
if (timerData) {
|
|
177
|
-
// Stop the timer and round result for readability.
|
|
178
|
-
var et = timerData.timer();
|
|
179
|
-
log.debug("[TIME TRACKER]: [" + task + "] took " + et + "ms to finish.");
|
|
180
|
-
// Check if we have a tracker callback.
|
|
181
|
-
if (timerData.cb) {
|
|
182
|
-
// If we have a callback, we call it with the elapsed time of the task and then delete the reference.
|
|
183
|
-
timerData.cb(et);
|
|
184
|
-
}
|
|
185
|
-
// Remove the task tracking reference.
|
|
186
|
-
delete timers[timerName];
|
|
187
|
-
return et;
|
|
188
|
-
}
|
|
189
|
-
},
|
|
190
|
-
/**
|
|
191
|
-
* The constants shortcut for the task names.
|
|
192
|
-
*/
|
|
193
|
-
TaskNames: CONSTANTS
|
|
194
|
-
};
|
|
@@ -1,226 +0,0 @@
|
|
|
1
|
-
import { uniqueId } from '../lang';
|
|
2
|
-
import { timer } from './timer';
|
|
3
|
-
import { thenable } from '../promise/thenable';
|
|
4
|
-
import { ILogger } from '../../logger/types';
|
|
5
|
-
import { IResponse } from '../../services/types';
|
|
6
|
-
|
|
7
|
-
// Based on ProducerMetricsCollector and ClientCollector classes
|
|
8
|
-
interface MetricsCollector {
|
|
9
|
-
// ProducerMetricsCollector API
|
|
10
|
-
countException(): void,
|
|
11
|
-
count(status: number): void,
|
|
12
|
-
latency(ms: number): void,
|
|
13
|
-
|
|
14
|
-
// ClientCollector API
|
|
15
|
-
ready(ms: number): void,
|
|
16
|
-
getTreatment(ms: number): void,
|
|
17
|
-
getTreatments(ms: number): void,
|
|
18
|
-
getTreatmentWithConfig(ms: number): void,
|
|
19
|
-
getTreatmentsWithConfig(ms: number): void,
|
|
20
|
-
|
|
21
|
-
[method: string]: (ms: number) => void,
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
// Map we will use for storing timers data
|
|
25
|
-
const timers: Record<string, {
|
|
26
|
-
cb: false | ((et: number) => void),
|
|
27
|
-
timer: () => number
|
|
28
|
-
}> = {};
|
|
29
|
-
|
|
30
|
-
// Tasks constants
|
|
31
|
-
const CONSTANTS = {
|
|
32
|
-
SDK_READY: 'Getting ready - Split SDK',
|
|
33
|
-
SDK_GET_TREATMENT: 'SDK - Get Treatment',
|
|
34
|
-
SDK_GET_TREATMENTS: 'SDK - Get Treatments',
|
|
35
|
-
SDK_GET_TREATMENT_WITH_CONFIG: 'SDK - Get Treatment with config',
|
|
36
|
-
SDK_GET_TREATMENTS_WITH_CONFIG: 'SDK - Get Treatments with config',
|
|
37
|
-
SPLITS_READY: 'Getting ready - Splits',
|
|
38
|
-
SEGMENTS_READY: 'Getting ready - Segments',
|
|
39
|
-
METRICS_PUSH: 'Pushing - Metrics',
|
|
40
|
-
IMPRESSIONS_PUSH: 'Pushing - Impressions',
|
|
41
|
-
EVENTS_PUSH: 'Pushing - Events',
|
|
42
|
-
MY_SEGMENTS_FETCH: 'Fetching - My Segments',
|
|
43
|
-
SEGMENTS_FETCH: 'Fetching - Segments',
|
|
44
|
-
SPLITS_FETCH: 'Fetching - Splits'
|
|
45
|
-
};
|
|
46
|
-
// Tasks callbacks, if any
|
|
47
|
-
const CALLBACKS = {
|
|
48
|
-
[CONSTANTS.SDK_READY]: {
|
|
49
|
-
collector: 'client',
|
|
50
|
-
method: 'ready'
|
|
51
|
-
},
|
|
52
|
-
[CONSTANTS.SDK_GET_TREATMENT]: {
|
|
53
|
-
collector: 'client',
|
|
54
|
-
method: 'getTreatment'
|
|
55
|
-
},
|
|
56
|
-
[CONSTANTS.SDK_GET_TREATMENTS]: {
|
|
57
|
-
collector: 'client',
|
|
58
|
-
method: 'getTreatments'
|
|
59
|
-
},
|
|
60
|
-
[CONSTANTS.SDK_GET_TREATMENT_WITH_CONFIG]: {
|
|
61
|
-
collector: 'client',
|
|
62
|
-
method: 'getTreatmentWithConfig'
|
|
63
|
-
},
|
|
64
|
-
[CONSTANTS.SDK_GET_TREATMENTS_WITH_CONFIG]: {
|
|
65
|
-
collector: 'client',
|
|
66
|
-
method: 'getTreatmentsWithConfig'
|
|
67
|
-
},
|
|
68
|
-
[CONSTANTS.MY_SEGMENTS_FETCH]: {
|
|
69
|
-
collector: 'mySegments',
|
|
70
|
-
method: 'latency'
|
|
71
|
-
},
|
|
72
|
-
[CONSTANTS.SEGMENTS_FETCH]: {
|
|
73
|
-
collector: 'segmentChanges',
|
|
74
|
-
method: 'latency'
|
|
75
|
-
},
|
|
76
|
-
[CONSTANTS.SPLITS_FETCH]: {
|
|
77
|
-
collector: 'splitChanges',
|
|
78
|
-
method: 'latency'
|
|
79
|
-
}
|
|
80
|
-
};
|
|
81
|
-
/**
|
|
82
|
-
* Generates the timer keys using the task name and a modifier, if any.
|
|
83
|
-
* @param {string} task - The task name
|
|
84
|
-
* @param {number | string} modifier - (optional) The modifier, if any.
|
|
85
|
-
* @return {string} The generated timer key
|
|
86
|
-
*/
|
|
87
|
-
function generateTimerKey(task: string, modifier?: number | string) { return modifier ? task + modifier : task; }
|
|
88
|
-
/**
|
|
89
|
-
* Given the collectors map, it returns the specific collector for a given task.
|
|
90
|
-
*
|
|
91
|
-
* @param {string} task - The task name
|
|
92
|
-
* @param {Object} collectors - The collectors map
|
|
93
|
-
*/
|
|
94
|
-
function getCollectorForTask(task: string, collectors?: Record<string, MetricsCollector>): false | MetricsCollector {
|
|
95
|
-
const callbackData = CALLBACKS[task];
|
|
96
|
-
|
|
97
|
-
if (callbackData && collectors) return collectors[callbackData.collector];
|
|
98
|
-
|
|
99
|
-
return false;
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Given a collector and a task, returns the callback function that should be called when we stop the timer.
|
|
103
|
-
*
|
|
104
|
-
* @param {string} task - The task name
|
|
105
|
-
* @param {Object} collector - The collector object for the task
|
|
106
|
-
*/
|
|
107
|
-
function getCallbackForTask(task: string, collector: MetricsCollector | false): ((ms: number) => void) | false {
|
|
108
|
-
const callbackData = CALLBACKS[task];
|
|
109
|
-
|
|
110
|
-
if (callbackData && collector) return collector[callbackData.method];
|
|
111
|
-
|
|
112
|
-
return false;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
// Our "time tracker" API
|
|
116
|
-
export const TrackerAPI = {
|
|
117
|
-
/**
|
|
118
|
-
* "Private" method, used to attach count/countException and stop callbacks to a promise.
|
|
119
|
-
*
|
|
120
|
-
* @param {ILogger} log - Logger.
|
|
121
|
-
* @param {Promise} promise - The promise we want to attach the callbacks.
|
|
122
|
-
* @param {string} task - The name of the task.
|
|
123
|
-
* @param {number | string} modifier - (optional) The modifier for the task, if any.
|
|
124
|
-
*/
|
|
125
|
-
__attachToPromise(log: ILogger, promise: Promise<IResponse>, task: string, collector: false | MetricsCollector, modifier?: number | string) {
|
|
126
|
-
return promise.then(resp => {
|
|
127
|
-
this.stop(log, task, modifier);
|
|
128
|
-
|
|
129
|
-
if (collector && collector.count) collector.count(resp.status);
|
|
130
|
-
|
|
131
|
-
return resp;
|
|
132
|
-
})
|
|
133
|
-
.catch(err => {
|
|
134
|
-
this.stop(log, task, modifier);
|
|
135
|
-
|
|
136
|
-
if (collector && collector.countException) collector.countException();
|
|
137
|
-
|
|
138
|
-
throw err;
|
|
139
|
-
});
|
|
140
|
-
},
|
|
141
|
-
/**
|
|
142
|
-
* Starts tracking the time for a given task. All tasks tracked are considered "unique" because
|
|
143
|
-
* there may be multiple SDK instances tracking a "generic" task, making any task non-generic.
|
|
144
|
-
*
|
|
145
|
-
* @param {ILogger} log - Logger.
|
|
146
|
-
* @param {string} task - The task we are starting.
|
|
147
|
-
* @param {Object} collectors - The collectors map.
|
|
148
|
-
* @param {Promise} promise - (optional) The promise we are tracking.
|
|
149
|
-
* @return {Function | Promise} The stop function for this specific task or the promise received with the callbacks registered.
|
|
150
|
-
*/
|
|
151
|
-
start(log: ILogger, task: string, collectors?: Record<string, MetricsCollector>, promise?: Promise<IResponse>, now: () => number = Date.now): Promise<IResponse> | (() => number) {
|
|
152
|
-
const taskUniqueId = uniqueId();
|
|
153
|
-
const taskCollector = getCollectorForTask(task, collectors);
|
|
154
|
-
let result;
|
|
155
|
-
|
|
156
|
-
// If we are registering a promise with this task, we should count the status and the exceptions as well
|
|
157
|
-
// as stopping the task when the promise resolves. Then return the promise
|
|
158
|
-
if (thenable(promise)) {
|
|
159
|
-
result = this.__attachToPromise(log, promise, task, taskCollector, taskUniqueId);
|
|
160
|
-
} else {
|
|
161
|
-
// If not, we return the stop function, as it will be stopped manually.
|
|
162
|
-
result = this.stop.bind(this, log, task, taskUniqueId);
|
|
163
|
-
if (CALLBACKS[task] && !taskCollector) {
|
|
164
|
-
// and provide a way for a defered setup of the collector, if needed.
|
|
165
|
-
// @ts-expect-error
|
|
166
|
-
result.setCollectorForTask = this.setCollectorForTask.bind(this, task, taskUniqueId);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
// We start the timer, with an uniqueId attached to it's name, and save tracking info for this task.
|
|
171
|
-
const trackingKey = generateTimerKey(task, taskUniqueId);
|
|
172
|
-
const cb = getCallbackForTask(task, taskCollector);
|
|
173
|
-
timers[trackingKey] = {
|
|
174
|
-
cb,
|
|
175
|
-
timer: timer(now)
|
|
176
|
-
};
|
|
177
|
-
|
|
178
|
-
return result as () => number;
|
|
179
|
-
},
|
|
180
|
-
/**
|
|
181
|
-
* Setup the collector for a task that reports metrics.
|
|
182
|
-
*
|
|
183
|
-
* @param {string} task - The task name
|
|
184
|
-
* @param {number | string} taskUniqueId - The unique identifier for this task
|
|
185
|
-
* @param {Object} collectors - The collectors map.
|
|
186
|
-
*/
|
|
187
|
-
setCollectorForTask(task: string, taskUniqueId: number | string, collectors: Record<string, MetricsCollector>) {
|
|
188
|
-
const taskCollector = getCollectorForTask(task, collectors);
|
|
189
|
-
|
|
190
|
-
if (taskCollector) {
|
|
191
|
-
const trackingKey = generateTimerKey(task, taskUniqueId);
|
|
192
|
-
timers[trackingKey].cb = getCallbackForTask(task, taskCollector);
|
|
193
|
-
}
|
|
194
|
-
},
|
|
195
|
-
/**
|
|
196
|
-
* Stops the tracking of a given task.
|
|
197
|
-
*
|
|
198
|
-
* @param {ILogger} log - Logger.
|
|
199
|
-
* @param {string} task - The task we are starting.
|
|
200
|
-
* @param {number | string} modifier - (optional) The modifier for that specific task.
|
|
201
|
-
*/
|
|
202
|
-
stop(log: ILogger, task: string, modifier?: number | string) {
|
|
203
|
-
const timerName = generateTimerKey(task, modifier);
|
|
204
|
-
const timerData = timers[timerName];
|
|
205
|
-
if (timerData) {
|
|
206
|
-
// Stop the timer and round result for readability.
|
|
207
|
-
const et = timerData.timer();
|
|
208
|
-
log.debug(`[TIME TRACKER]: [${task}] took ${et}ms to finish.`);
|
|
209
|
-
|
|
210
|
-
// Check if we have a tracker callback.
|
|
211
|
-
if (timerData.cb) {
|
|
212
|
-
// If we have a callback, we call it with the elapsed time of the task and then delete the reference.
|
|
213
|
-
timerData.cb(et);
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
// Remove the task tracking reference.
|
|
217
|
-
delete timers[timerName];
|
|
218
|
-
|
|
219
|
-
return et;
|
|
220
|
-
}
|
|
221
|
-
},
|
|
222
|
-
/**
|
|
223
|
-
* The constants shortcut for the task names.
|
|
224
|
-
*/
|
|
225
|
-
TaskNames: CONSTANTS
|
|
226
|
-
};
|