@@ -3,7 +3,7 @@ var iaLabels;
3
3
var iaLocations = [ ] ;
4
4
var iaGeoLoc ;
5
5
var g = { } ;
6
- var jPathColors = [ ] ;
6
+ var jPathsAvailable = { } ;
7
7
8
8
function setupDebug ( src , dst ) {
9
9
var src = $ ( '#ia_cli' ) . val ( ) ;
@@ -26,14 +26,99 @@ function path_colors(n) {
26
26
}
27
27
28
28
function getPathColor ( hops ) {
29
- var idx = jPathColors . indexOf ( hops + '' ) ;
30
- if ( idx < 0 ) {
29
+ if ( ! jPathsAvailable [ hops ] ) {
31
30
return cMissingPath ;
32
31
} else {
33
- return path_colors ( idx ) ;
32
+ return jPathsAvailable [ hops ] . color ;
34
33
}
35
34
}
36
35
36
+ /**
37
+ * Updates statistics.
38
+ */
39
+ function updateStats ( fStat , oldStat ) {
40
+ var newStat = { }
41
+ newStat . Last = fStat ;
42
+ newStat . Num = oldStat ? ( oldStat . Num + 1 ) : 1 ;
43
+ newStat . Avg = oldStat ? ( ( ( oldStat . Avg * oldStat . Num ) + fStat ) / newStat . Num )
44
+ : fStat ;
45
+ newStat . Min = oldStat ? Math . min ( fStat , oldStat . Min ) : fStat ;
46
+ newStat . Max = oldStat ? Math . max ( fStat , oldStat . Max ) : fStat ;
47
+ return newStat ;
48
+ }
49
+
50
+ function getPathLatencyLast ( hops ) {
51
+ return getPathLatency ( hops , false ) ;
52
+ }
53
+
54
+ function getPathLatencyAvg ( hops ) {
55
+ return getPathLatency ( hops , true ) ;
56
+ }
57
+
58
+ /**
59
+ * Returns array of interface and full path latency stats.
60
+ */
61
+ function getPathLatency ( hops , avg ) {
62
+ var path = { } ;
63
+ if ( jPathsAvailable [ hops ] ) {
64
+ path = jPathsAvailable [ hops ] ;
65
+ }
66
+ var latencies = [ ] ;
67
+ for ( var i = 0 ; i < path . interfaces . length ; i ++ ) {
68
+ if ( path . interfaces [ i ] . latency ) {
69
+ latencies . push ( avg ? path . interfaces [ i ] . latency . Last
70
+ : path . interfaces [ i ] . latency . Avg ) ;
71
+ } else {
72
+ latencies . push ( undefined ) ;
73
+ }
74
+ }
75
+ if ( path . latency ) {
76
+ latencies . push ( avg ? path . latency . Last : path . latency . Avg ) ;
77
+ } else {
78
+ latencies . push ( undefined ) ;
79
+ }
80
+ return latencies ;
81
+ }
82
+
83
+ function setEchoLatency ( hops , latency ) {
84
+ var path = { } ;
85
+ if ( jPathsAvailable [ hops ] ) {
86
+ path = jPathsAvailable [ hops ] ;
87
+ }
88
+ path . latency = updateStats ( latency , path . latency ) ;
89
+ var latStr = parseFloat ( path . latency . Last ) . toFixed ( 1 ) ;
90
+ $ ( '#path-lat-' + path . listIdx ) . html ( latStr ) ;
91
+ jPathsAvailable [ hops ] = path ;
92
+ }
93
+
94
+ function setTracerouteLatency ( hops , interfaces ) {
95
+ var path = { } ;
96
+ if ( jPathsAvailable [ hops ] ) {
97
+ path = jPathsAvailable [ hops ] ;
98
+ }
99
+ for ( var i = 0 ; i < interfaces . length ; i ++ ) {
100
+ var if_ = interfaces [ i ] ;
101
+ if ( i < interfaces . length - 1 ) {
102
+ path . interfaces [ i ] . addr = if_ . HopAddr ;
103
+ path . interfaces [ i ] . latency = updateStats ( if_ . RespTime1 ,
104
+ path . interfaces [ i ] . latency ) ;
105
+ path . interfaces [ i ] . latency = updateStats ( if_ . RespTime2 ,
106
+ path . interfaces [ i ] . latency ) ;
107
+ path . interfaces [ i ] . latency = updateStats ( if_ . RespTime3 ,
108
+ path . interfaces [ i ] . latency ) ;
109
+ var latStr = parseFloat ( path . interfaces [ i ] . latency . Last ) . toFixed ( 1 ) ;
110
+ $ ( '#path-lat-' + path . listIdx + '-' + i ) . html ( latStr ) ;
111
+ } else {
112
+ path . latency = updateStats ( if_ . RespTime1 , path . latency ) ;
113
+ path . latency = updateStats ( if_ . RespTime2 , path . latency ) ;
114
+ path . latency = updateStats ( if_ . RespTime3 , path . latency ) ;
115
+ var latStr = parseFloat ( path . latency . Last ) . toFixed ( 1 ) ;
116
+ $ ( '#path-lat-' + path . listIdx ) . html ( latStr ) ;
117
+ }
118
+ }
119
+ jPathsAvailable [ hops ] = path ;
120
+ }
121
+
37
122
function isConfigComplete ( data , textStatus , jqXHR ) {
38
123
console . log ( JSON . stringify ( data ) ) ;
39
124
g [ 'nodes_xml_url' ] = data . nodes_xml_url ;
@@ -376,11 +461,18 @@ function get_path_html(paths, csegs, usegs, dsegs, show_segs) {
376
461
if_ = ent . Path . Interfaces ;
377
462
var hops = if_ . length / 2 ;
378
463
379
- var style = "style='background-color: "
380
- + getPathColor ( formatPathJson ( paths , parseInt ( p ) ) ) + "; '" ;
381
- html += "<li seg-type='PATH' seg-num=" + p + "><a " + style
382
- + " href='#'>PATH " + ( parseInt ( p ) + 1 )
383
- + "</a> <span class='badge'>" + hops + "</span>" ;
464
+ var pathStr = formatPathJson ( paths , parseInt ( p ) ) ;
465
+ var latencies = getPathLatencyAvg ( pathStr ) ;
466
+ var latencyPath = latencies [ latencies . length - 1 ] ;
467
+ var latPathStr = latencyPath ? parseFloat ( latencyPath ) . toFixed ( 1 ) : '' ;
468
+ var aStyle = "style='background-color:" + getPathColor ( pathStr ) + ";'" ;
469
+ var latStyle = "style='color:purple; position:absolute; right:0;'" ;
470
+ html += "<li seg-type='PATH' seg-num=" + p + " path='" + pathStr
471
+ + "'><a class='path-text' " + aStyle
472
+ + " href='#'><span style='color: white;'>PATH "
473
+ + ( parseInt ( p ) + 1 ) + "</span></a> <span class='badge'>" + hops
474
+ + "</span> <span id='path-lat-" + p + "' " + latStyle + ">"
475
+ + latPathStr + "</span>" ;
384
476
exp . setUTCSeconds ( ent . Path . ExpTime ) ;
385
477
html += "<ul>" ;
386
478
html += "<li><a href='#'>Mtu: " + ent . Path . Mtu + "</a>" ;
@@ -396,8 +488,11 @@ function get_path_html(paths, csegs, usegs, dsegs, show_segs) {
396
488
html += "<li><a href='#'>Expiration: " + exp . toLocaleDateString ( ) + " "
397
489
+ exp . toLocaleTimeString ( ) + "</a>" ;
398
490
for ( i in if_ ) {
491
+ var latIfStr = latencies [ i ] ? parseFloat ( latencies [ i ] ) . toFixed ( 1 )
492
+ : '' ;
399
493
html += "<li><a href='#'>" + iaRaw2Read ( if_ [ i ] . RawIsdas ) + " ("
400
- + if_ [ i ] . IfID + ")</a>" ;
494
+ + if_ [ i ] . IfID + ")</a> <span id='path-lat-" + p + "-" + i
495
+ + "' " + latStyle + ">" + latIfStr + "</span>" ;
401
496
}
402
497
html += "</ul>" ;
403
498
}
@@ -662,6 +757,34 @@ function get_nonseg_links(paths, lType) {
662
757
return hops ;
663
758
}
664
759
760
+ function addAvailablePaths ( paths ) {
761
+ Object . keys ( jPathsAvailable ) . forEach ( function ( key ) {
762
+ jPathsAvailable [ key ] . listIdx = undefined ; // reset
763
+ } ) ;
764
+ for ( var idx = 0 ; idx < paths . length ; idx ++ ) {
765
+ var hops = formatPathJson ( paths , idx , 'PATH' ) ;
766
+ if ( ! jPathsAvailable [ hops ] ) {
767
+ jPathsAvailable [ hops ] = { } ;
768
+ }
769
+ // update path preserving old values
770
+ var path = jPathsAvailable [ hops ] ;
771
+ var pathLen = Object . keys ( jPathsAvailable ) . length ;
772
+ path . interfaces = [ ] ;
773
+ var ifs = paths [ idx ] . Entry . Path . Interfaces ;
774
+ for ( var i = 0 ; i < ifs . length ; i ++ ) {
775
+ var if_ = { } ;
776
+ if_ . ifid = ifs [ i ] . IfID ;
777
+ if_ . isdas = iaRaw2Read ( ifs [ i ] . RawIsdas ) ;
778
+ path . interfaces . push ( if_ ) ;
779
+ }
780
+ path . expTime = paths [ idx ] . Entry . Path . ExpTime ;
781
+ path . mtu = paths [ idx ] . Entry . Path . Mtu ;
782
+ path . color = path_colors ( pathLen - 1 ) ;
783
+ path . listIdx = idx ;
784
+ jPathsAvailable [ hops ] = path ;
785
+ }
786
+ }
787
+
665
788
function requestPaths ( ) {
666
789
// make sure to get path topo after IAs are loaded
667
790
var form_data = $ ( '#command-form' ) . serializeArray ( ) ;
@@ -685,12 +808,7 @@ function requestPaths() {
685
808
resDown = resSegs . down_segments ;
686
809
687
810
// store incoming paths
688
- for ( var idx = 0 ; idx < resPath . if_lists . length ; idx ++ ) {
689
- var hops = formatPathString ( resPath , idx , 'PATH' ) ;
690
- if ( ! jPathColors . includes ( hops ) ) {
691
- jPathColors . push ( hops ) ;
692
- }
693
- }
811
+ addAvailablePaths ( data . paths ) ;
694
812
695
813
jTopo = get_json_path_links ( resPath , resCore , resUp , resDown ) ;
696
814
$ ( '#path-info' ) . html (
0 commit comments