Skip to content

Commit d34f94b

Browse files
authored
Merge pull request scratchfoundation#58 from cwillisf/fix-telemetry-init
fix telemetry init and enforce queue length limit
2 parents bfb4710 + 02b06b2 commit d34f94b

File tree

1 file changed

+58
-18
lines changed

1 file changed

+58
-18
lines changed

src/main/telemetry/TelemetryClient.js

Lines changed: 58 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ const TelemetryServerURL = Object.freeze({
2020
staging: 'http://scratch-telemetry-s.us-east-1.elasticbeanstalk.com/',
2121
production: 'https://telemetry.scratch.mit.edu/'
2222
});
23+
const DefaultServerURL = (
24+
process.env.NODE_ENV === 'production' ? TelemetryServerURL.production : TelemetryServerURL.staging
25+
);
26+
27+
/**
28+
* Default name for persistent configuration & queue storage
29+
*/
30+
const DefaultStoreName = 'telemetry';
2331

2432
/**
2533
* Default interval, in seconds, between delivery attempts
@@ -31,6 +39,17 @@ const DefaultDeliveryInterval = 60;
3139
*/
3240
const DefaultNetworkCheckInterval = 300;
3341

42+
/**
43+
* Default limit on the number of queued events
44+
*/
45+
const DefaultQueueLimit = 100;
46+
47+
/**
48+
* Default limit on the number of delivery attempts for each event
49+
*/
50+
const DeliveryAttemptLimit = 3;
51+
52+
3453
/**
3554
* Client interface for the Scratch telemetry service.
3655
*
@@ -45,32 +64,39 @@ class TelemetryClient {
4564
* @param {object} [options] - optional configuration settings for this client
4665
* @property {string} [storeName] - optional name for persistent config/queue storage (default: 'telemetry')
4766
* @property {string} [clientId] - optional UUID for this client (default: automatically determine a UUID)
48-
* @property {string} [url] - optional telemetry service endpoint URL (default: automatically choose a server)
67+
* @property {string} [serverURL] - optional telemetry service endpoint URL (default: automatically choose a server)
4968
* @property {boolean} [didOptIn] - optional flag for whether the user opted into telemetry service (default: false)
5069
* @property {int} [deliveryInterval] - optional number of seconds between delivery attempts (default: 60)
51-
* @property {int} [networkInterval] - optional number of seconds between connectivity checks (default: 300)
70+
* @property {int} [networkCheckInterval] - optional number of seconds between connectivity checks (default: 300)
5271
* @property {int} [queueLimit] - optional limit on the number of queued events (default: 100)
53-
* @property {int} [attemptLimit] - optional limit on the number of delivery attempts for each event (default: 3)
72+
* @property {int} [deliveryAttemptLimit] - optional limit on delivery attempts for each event (default: 3)
5473
*/
55-
constructor (options = null) {
56-
options = options || {};
57-
74+
constructor ({
75+
storeName = DefaultStoreName,
76+
clientID, // undefined = load or create
77+
serverURL, // undefined = automatic
78+
didOptIn, // undefined = show prompt
79+
deliveryInterval = DefaultDeliveryInterval,
80+
networkCheckInterval = DefaultNetworkCheckInterval,
81+
queueLimit = DefaultQueueLimit,
82+
deliveryAttemptLimit = DeliveryAttemptLimit
83+
} = {}) {
5884
/**
5985
* Persistent storage for the client ID, opt in flag, and packet queue.
6086
*/
6187
this._store = new ElectronStore({
62-
name: options.storeName || 'telemetry'
88+
name: storeName
6389
});
6490
console.log(`Telemetry configuration storage path: ${this._store.path}`);
6591

66-
if (options.hasOwnProperty('clientID')) {
67-
this.clientID = options.clientID;
92+
if (clientID) {
93+
this.clientID = clientID;
6894
} else if (!this._store.has('clientID')) {
6995
this.clientID = uuidv1();
7096
}
7197

72-
if (options.hasOwnProperty('optIn')) {
73-
this.didOptIn = options.didOptIn;
98+
if (typeof didOptIn !== 'undefined') {
99+
this.didOptIn = didOptIn;
74100
}
75101

76102
/**
@@ -81,7 +107,7 @@ class TelemetryClient {
81107
/**
82108
* Server URL
83109
*/
84-
this._serverURL = options.url || TelemetryServerURL.staging;
110+
this._serverURL = serverURL || DefaultServerURL;
85111

86112
/**
87113
* Can we currently reach the telemetry service?
@@ -91,13 +117,22 @@ class TelemetryClient {
91117
/**
92118
* Try to deliver telemetry packets at this interval
93119
*/
94-
this._deliveryInterval = (options.deliveryInterval > 0) ? options.deliveryInterval : DefaultDeliveryInterval;
120+
this._deliveryInterval = (deliveryInterval > 0) ? deliveryInterval : DefaultDeliveryInterval;
95121

96122
/**
97123
* Check for connectivity at this interval
98124
*/
99-
this._networkCheckInterval =
100-
(options.networkCheckInterval > 0) ? options.networkCheckInterval : DefaultNetworkCheckInterval;
125+
this._networkCheckInterval = (networkCheckInterval > 0) ? networkCheckInterval : DefaultNetworkCheckInterval;
126+
127+
/**
128+
* Queue at most this many events
129+
*/
130+
this._queueLimit = (queueLimit > 0) ? queueLimit : DefaultQueueLimit;
131+
132+
/**
133+
* Attempt to deliver an event at most this many times
134+
*/
135+
this._deliveryAttemptLimit = (deliveryAttemptLimit > 0) ? deliveryAttemptLimit : DeliveryAttemptLimit;
101136

102137
/**
103138
* Bind event handlers
@@ -121,9 +156,13 @@ class TelemetryClient {
121156
* Stop this client. Do not use this object after disposal.
122157
*/
123158
dispose () {
124-
if (this._deliveryInterval !== null) {
159+
if (this._networkTimer !== null) {
160+
clearInterval(this._networkTimer);
161+
this._networkTimer = null;
162+
}
163+
if (this._deliveryTimer !== null) {
125164
clearInterval(this._deliveryTimer);
126-
this._deliveryInterval = null;
165+
this._deliveryTimer = null;
127166
}
128167
}
129168

@@ -183,6 +222,7 @@ class TelemetryClient {
183222
packet
184223
};
185224
this._packetQueue.push(packetInfo);
225+
this._packetQueue.splice(0, this._packetQueue.length - this._queueLimit); // enforce queue length limit
186226
this.saveQueue();
187227
}
188228

@@ -220,7 +260,7 @@ class TelemetryClient {
220260
// TODO: check if the failure is because there's no Internet connection and if so refund the attempt
221261
const packetFailed = err || (res.statusCode !== 200);
222262
if (packetFailed) {
223-
if (packetInfo.attempts < this._attemptsLimit) {
263+
if (packetInfo.attempts < this._deliveryAttemptLimit) {
224264
this._packetQueue.push(packetInfo);
225265
} else {
226266
console.warn('Dropping packet which exceeded retry limit', packet);

0 commit comments

Comments
 (0)