@@ -20,6 +20,14 @@ const TelemetryServerURL = Object.freeze({
20
20
staging : 'http://scratch-telemetry-s.us-east-1.elasticbeanstalk.com/' ,
21
21
production : 'https://telemetry.scratch.mit.edu/'
22
22
} ) ;
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' ;
23
31
24
32
/**
25
33
* Default interval, in seconds, between delivery attempts
@@ -31,6 +39,17 @@ const DefaultDeliveryInterval = 60;
31
39
*/
32
40
const DefaultNetworkCheckInterval = 300 ;
33
41
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
+
34
53
/**
35
54
* Client interface for the Scratch telemetry service.
36
55
*
@@ -45,32 +64,39 @@ class TelemetryClient {
45
64
* @param {object } [options] - optional configuration settings for this client
46
65
* @property {string } [storeName] - optional name for persistent config/queue storage (default: 'telemetry')
47
66
* @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)
49
68
* @property {boolean } [didOptIn] - optional flag for whether the user opted into telemetry service (default: false)
50
69
* @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)
52
71
* @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)
54
73
*/
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
+ } = { } ) {
58
84
/**
59
85
* Persistent storage for the client ID, opt in flag, and packet queue.
60
86
*/
61
87
this . _store = new ElectronStore ( {
62
- name : options . storeName || 'telemetry'
88
+ name : storeName
63
89
} ) ;
64
90
console . log ( `Telemetry configuration storage path: ${ this . _store . path } ` ) ;
65
91
66
- if ( options . hasOwnProperty ( ' clientID' ) ) {
67
- this . clientID = options . clientID ;
92
+ if ( clientID ) {
93
+ this . clientID = clientID ;
68
94
} else if ( ! this . _store . has ( 'clientID' ) ) {
69
95
this . clientID = uuidv1 ( ) ;
70
96
}
71
97
72
- if ( options . hasOwnProperty ( 'optIn' ) ) {
73
- this . didOptIn = options . didOptIn ;
98
+ if ( typeof didOptIn !== 'undefined' ) {
99
+ this . didOptIn = didOptIn ;
74
100
}
75
101
76
102
/**
@@ -81,7 +107,7 @@ class TelemetryClient {
81
107
/**
82
108
* Server URL
83
109
*/
84
- this . _serverURL = options . url || TelemetryServerURL . staging ;
110
+ this . _serverURL = serverURL || DefaultServerURL ;
85
111
86
112
/**
87
113
* Can we currently reach the telemetry service?
@@ -91,13 +117,22 @@ class TelemetryClient {
91
117
/**
92
118
* Try to deliver telemetry packets at this interval
93
119
*/
94
- this . _deliveryInterval = ( options . deliveryInterval > 0 ) ? options . deliveryInterval : DefaultDeliveryInterval ;
120
+ this . _deliveryInterval = ( deliveryInterval > 0 ) ? deliveryInterval : DefaultDeliveryInterval ;
95
121
96
122
/**
97
123
* Check for connectivity at this interval
98
124
*/
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 ;
101
136
102
137
/**
103
138
* Bind event handlers
@@ -121,9 +156,13 @@ class TelemetryClient {
121
156
* Stop this client. Do not use this object after disposal.
122
157
*/
123
158
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 ) {
125
164
clearInterval ( this . _deliveryTimer ) ;
126
- this . _deliveryInterval = null ;
165
+ this . _deliveryTimer = null ;
127
166
}
128
167
}
129
168
@@ -183,6 +222,7 @@ class TelemetryClient {
183
222
packet
184
223
} ;
185
224
this . _packetQueue . push ( packetInfo ) ;
225
+ this . _packetQueue . splice ( 0 , this . _packetQueue . length - this . _queueLimit ) ; // enforce queue length limit
186
226
this . saveQueue ( ) ;
187
227
}
188
228
@@ -220,7 +260,7 @@ class TelemetryClient {
220
260
// TODO: check if the failure is because there's no Internet connection and if so refund the attempt
221
261
const packetFailed = err || ( res . statusCode !== 200 ) ;
222
262
if ( packetFailed ) {
223
- if ( packetInfo . attempts < this . _attemptsLimit ) {
263
+ if ( packetInfo . attempts < this . _deliveryAttemptLimit ) {
224
264
this . _packetQueue . push ( packetInfo ) ;
225
265
} else {
226
266
console . warn ( 'Dropping packet which exceeded retry limit' , packet ) ;
0 commit comments