@@ -16,7 +16,8 @@ angular.module('openshiftConsole')
16
16
pod : '=' ,
17
17
sparklineWidth : '=?' ,
18
18
sparklineHeight : '=?' ,
19
- includedMetrics : '=?' // defaults to ["cpu", "memory", "network"]
19
+ includedMetrics : '=?' , // defaults to ["cpu", "memory", "network"]
20
+ alerts : '=?'
20
21
} ,
21
22
templateUrl : 'views/directives/pod-metrics.html' ,
22
23
link : function ( scope ) {
@@ -27,6 +28,7 @@ angular.module('openshiftConsole')
27
28
var getCPULimit = $parse ( 'resources.limits.cpu' ) ;
28
29
29
30
var updateInterval = 60 * 1000 ; // 60 seconds
31
+
30
32
// Number of data points to display on the chart.
31
33
var numDataPoints = 30 ;
32
34
@@ -382,9 +384,61 @@ angular.module('openshiftConsole')
382
384
return null ;
383
385
}
384
386
387
+ // Track the number of consecutive failures.
388
+ var failureCount = 0 ;
389
+
390
+ function metricsSucceeded ( ) {
391
+ // Reset the number of failures on a successful request.
392
+ failureCount = 0 ;
393
+ }
394
+
395
+ // If the first request for metrics fails, show an empty state error message.
396
+ // Otherwise show an alert if more than one consecutive request fails.
397
+ function metricsFailed ( response ) {
398
+ if ( destroyed ) {
399
+ return ;
400
+ }
401
+
402
+ failureCount ++ ;
403
+ if ( scope . noData ) {
404
+ // Show an empty state message if the first request for data fails.
405
+ scope . metricsError = {
406
+ status : _ . get ( response , 'status' , 0 ) ,
407
+ details : _ . get ( response , 'data.errorMsg' ) ||
408
+ _ . get ( response , 'statusText' ) ||
409
+ "Status code " + _ . get ( response , 'status' , 0 )
410
+ } ;
411
+ return ;
412
+ }
413
+
414
+ // If this is the first failure and a previous request succeeded, wait and try again.
415
+ if ( failureCount < 2 ) {
416
+ return ;
417
+ }
418
+
419
+ // Show an alert if we've failed more than once.
420
+ // Use scope.$id in the alert ID so that it is unique on pages that
421
+ // use the directive multiple times like monitoring.
422
+ var alertID = 'metrics-failed-' + scope . uniqueID ;
423
+ scope . alerts [ alertID ] = {
424
+ type : 'error' ,
425
+ message : 'An error occurred updating metrics for pod ' + _ . get ( scope , 'pod.metadata.name' , '<unknown>' ) + '.' ,
426
+ links : [ {
427
+ href : '' ,
428
+ label : 'Retry' ,
429
+ onClick : function ( ) {
430
+ delete scope . alerts [ alertID ] ;
431
+ // Reset failure count to 1 to trigger a retry.
432
+ failureCount = 1 ;
433
+ update ( ) ;
434
+ }
435
+ } ]
436
+ } ;
437
+ }
438
+
385
439
// Make sure there are no errors or missing data before updating.
386
440
function canUpdate ( ) {
387
- if ( scope . metricsError ) {
441
+ if ( scope . metricsError || failureCount > 1 ) {
388
442
return false ;
389
443
}
390
444
@@ -419,8 +473,9 @@ angular.module('openshiftConsole')
419
473
// time. This prevents an issue where the donut chart shows 0 for
420
474
// current usage if the client clock is ahead of the server clock.
421
475
var start = getStartTime ( ) ;
476
+ var allPromises = [ ] ;
422
477
angular . forEach ( scope . metrics , function ( metric ) {
423
- var promises = [ ] ;
478
+ var datasetPromises = [ ] ;
424
479
425
480
// On metrics that require more than one set of data (e.g. network
426
481
// incoming and outgoing traffic) we perform one request for each,
@@ -434,52 +489,40 @@ angular.module('openshiftConsole')
434
489
if ( ! config ) {
435
490
return ;
436
491
}
437
- promises . push ( MetricsService . get ( config ) ) ;
492
+ var promise = MetricsService . get ( config ) ;
493
+ datasetPromises . push ( promise ) ;
438
494
} ) ;
439
495
496
+ allPromises = allPromises . concat ( datasetPromises ) ;
497
+
440
498
// Collect all promises from every metric requested into one, so we
441
499
// have all data the chart wants at the time of the chart creation
442
500
// (or timeout updates, etc).
443
- $q . all ( promises ) . then (
444
- // success
445
- function ( responses ) {
446
- if ( destroyed ) {
447
- return ;
448
- }
449
-
450
- angular . forEach ( responses , function ( response ) {
451
- if ( ! response ) {
452
- return ;
453
- }
501
+ $q . all ( datasetPromises ) . then ( function ( responses ) {
502
+ if ( destroyed ) {
503
+ return ;
504
+ }
454
505
455
- var dataset = _ . find ( metric . datasets , {
456
- id : response . metricID
457
- } ) ;
458
- updateData ( dataset , response ) ;
459
- } ) ;
460
- updateChart ( metric ) ;
461
- } ,
462
- // failure
463
- function ( responses ) {
464
- if ( destroyed ) {
506
+ angular . forEach ( responses , function ( response ) {
507
+ if ( ! response ) {
465
508
return ;
466
509
}
467
510
468
- angular . forEach ( responses , function ( response ) {
469
- scope . metricsError = {
470
- status : _ . get ( response , 'status' , 0 ) ,
471
- details : _ . get ( response , 'data.errorMsg' ) ||
472
- _ . get ( response , 'statusText' ) ||
473
- "Status code " + _ . get ( response , 'status' , 0 )
474
- } ;
511
+ var dataset = _ . find ( metric . datasets , {
512
+ id : response . metricID
475
513
} ) ;
476
- }
477
- ) . finally ( function ( ) {
478
- // Even on errors mark metrics as loaded to replace the
479
- // "Loading..." message with "No metrics to display."
480
- scope . loaded = true ;
514
+ updateData ( dataset , response ) ;
515
+ } ) ;
516
+ updateChart ( metric ) ;
481
517
} ) ;
482
518
} ) ;
519
+
520
+ // Handle failures when any request fails.
521
+ $q . all ( allPromises ) . then ( metricsSucceeded , metricsFailed ) . finally ( function ( ) {
522
+ // Even on errors mark metrics as loaded to replace the
523
+ // "Loading..." message with "No metrics to display."
524
+ scope . loaded = true ;
525
+ } ) ;
483
526
}
484
527
485
528
// Updates immediately and then on options changes.
0 commit comments