@@ -38,12 +38,12 @@ interface MetricsData {
38
38
}
39
39
40
40
interface RegistrationData {
41
- appName : string ;
41
+ appName : string ;
42
42
instanceId : string ;
43
43
sdkVersion : string ;
44
44
strategies : string [ ] ;
45
- started : Date ;
46
- interval : number
45
+ started : Date ;
46
+ interval : number ;
47
47
}
48
48
49
49
export default class Metrics extends EventEmitter {
@@ -61,6 +61,8 @@ export default class Metrics extends EventEmitter {
61
61
62
62
private metricsJitter : number ;
63
63
64
+ private failures : number = 0 ;
65
+
64
66
private disabled : boolean ;
65
67
66
68
private url : string ;
@@ -111,21 +113,39 @@ export default class Metrics extends EventEmitter {
111
113
return getAppliedJitter ( this . metricsJitter ) ;
112
114
}
113
115
116
+ getFailures ( ) : number {
117
+ return this . failures ;
118
+ }
119
+
120
+ getInterval ( ) : number {
121
+ if ( this . metricsInterval === 0 ) {
122
+ return 0 ;
123
+ } else {
124
+ return this . metricsInterval +
125
+ ( this . failures * this . metricsInterval ) +
126
+ this . getAppliedJitter ( ) ;
127
+ }
128
+
129
+ }
130
+
114
131
private startTimer ( ) : void {
115
- if ( this . disabled ) {
132
+ if ( this . disabled || this . getInterval ( ) === 0 ) {
116
133
return ;
117
134
}
118
- this . timer = setTimeout ( ( ) => {
119
- this . sendMetrics ( ) ;
120
- } , this . metricsInterval + this . getAppliedJitter ( ) ) ;
135
+ this . timer = setTimeout (
136
+ ( ) => {
137
+ this . sendMetrics ( ) ;
138
+ } ,
139
+ this . getInterval ( ) ,
140
+ ) ;
121
141
122
142
if ( process . env . NODE_ENV !== 'test' && typeof this . timer . unref === 'function' ) {
123
143
this . timer . unref ( ) ;
124
144
}
125
145
}
126
146
127
147
start ( ) : void {
128
- if ( typeof this . metricsInterval === 'number' && this . metricsInterval > 0 ) {
148
+ if ( this . metricsInterval > 0 ) {
129
149
this . startTimer ( ) ;
130
150
this . registerInstance ( ) ;
131
151
}
@@ -170,6 +190,19 @@ export default class Metrics extends EventEmitter {
170
190
return true ;
171
191
}
172
192
193
+ configurationError ( url : string , statusCode : number ) {
194
+ this . emit ( UnleashEvents . Warn , `${ url } returning ${ statusCode } , stopping metrics` ) ;
195
+ this . metricsInterval = 0 ;
196
+ this . stop ( ) ;
197
+ }
198
+
199
+ backoff ( url : string , statusCode : number ) : void {
200
+ this . failures = Math . min ( 10 , this . failures + 1 ) ;
201
+ // eslint-disable-next-line max-len
202
+ this . emit ( UnleashEvents . Warn , `${ url } returning ${ statusCode } . Backing off to ${ this . failures } times normal interval` ) ;
203
+ this . startTimer ( ) ;
204
+ }
205
+
173
206
async sendMetrics ( ) : Promise < void > {
174
207
if ( this . disabled ) {
175
208
return ;
@@ -194,16 +227,22 @@ export default class Metrics extends EventEmitter {
194
227
timeout : this . timeout ,
195
228
httpOptions : this . httpOptions ,
196
229
} ) ;
197
- this . startTimer ( ) ;
198
- if ( res . status === 404 ) {
199
- this . emit ( UnleashEvents . Warn , `${ url } returning 404, stopping metrics` ) ;
200
- this . stop ( ) ;
201
- }
202
230
if ( ! res . ok ) {
231
+ if ( res . status === 404 || res . status === 403 || res . status == 401 ) {
232
+ this . configurationError ( url , res . status ) ;
233
+ } else if (
234
+ res . status === 429 ||
235
+ res . status === 500 ||
236
+ res . status === 502 ||
237
+ res . status === 503 ||
238
+ res . status === 504
239
+ ) {
240
+ this . backoff ( url , res . status ) ;
241
+ }
203
242
this . restoreBucket ( payload . bucket ) ;
204
- this . emit ( UnleashEvents . Warn , `${ url } returning ${ res . status } ` , await res . text ( ) ) ;
205
243
} else {
206
244
this . emit ( UnleashEvents . Sent , payload ) ;
245
+ this . reduceBackoff ( ) ;
207
246
}
208
247
} catch ( err ) {
209
248
this . restoreBucket ( payload . bucket ) ;
@@ -212,6 +251,11 @@ export default class Metrics extends EventEmitter {
212
251
}
213
252
}
214
253
254
+ reduceBackoff ( ) : void {
255
+ this . failures = Math . max ( 0 , this . failures - 1 ) ;
256
+ this . startTimer ( ) ;
257
+ }
258
+
215
259
assertBucket ( name : string ) : void {
216
260
if ( this . disabled ) {
217
261
return ;
@@ -243,7 +287,7 @@ export default class Metrics extends EventEmitter {
243
287
}
244
288
245
289
private increaseCounter ( name : string , enabled : boolean , inc = 1 ) : void {
246
- if ( inc === 0 ) {
290
+ if ( inc === 0 ) {
247
291
return ;
248
292
}
249
293
this . assertBucket ( name ) ;
@@ -252,8 +296,8 @@ export default class Metrics extends EventEmitter {
252
296
253
297
private increaseVariantCounter ( name : string , variantName : string , inc = 1 ) : void {
254
298
this . assertBucket ( name ) ;
255
- if ( this . bucket . toggles [ name ] . variants [ variantName ] ) {
256
- this . bucket . toggles [ name ] . variants [ variantName ] += inc
299
+ if ( this . bucket . toggles [ name ] . variants [ variantName ] ) {
300
+ this . bucket . toggles [ name ] . variants [ variantName ] += inc ;
257
301
} else {
258
302
this . bucket . toggles [ name ] . variants [ variantName ] = inc ;
259
303
}
@@ -276,7 +320,7 @@ export default class Metrics extends EventEmitter {
276
320
}
277
321
278
322
createMetricsData ( ) : MetricsData {
279
- const bucket = { ...this . bucket , stop : new Date ( ) } ;
323
+ const bucket = { ...this . bucket , stop : new Date ( ) } ;
280
324
this . resetBucket ( ) ;
281
325
return {
282
326
appName : this . appName ,
@@ -286,20 +330,20 @@ export default class Metrics extends EventEmitter {
286
330
}
287
331
288
332
private restoreBucket ( bucket : Bucket ) : void {
289
- if ( this . disabled ) {
333
+ if ( this . disabled ) {
290
334
return ;
291
335
}
292
336
this . bucket . start = bucket . start ;
293
337
294
338
const { toggles } = bucket ;
295
- Object . keys ( toggles ) . forEach ( toggleName => {
296
- const toggle = toggles [ toggleName ] ;
339
+ Object . keys ( toggles ) . forEach ( ( toggleName ) => {
340
+ const toggle = toggles [ toggleName ] ;
297
341
this . increaseCounter ( toggleName , true , toggle . yes ) ;
298
342
this . increaseCounter ( toggleName , false , toggle . no ) ;
299
343
300
- Object . keys ( toggle . variants ) . forEach ( variant => {
344
+ Object . keys ( toggle . variants ) . forEach ( ( variant ) => {
301
345
this . increaseVariantCounter ( toggleName , variant , toggle . variants [ variant ] ) ;
302
- } )
346
+ } ) ;
303
347
} ) ;
304
348
}
305
349
0 commit comments