You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ea...@apache.org on 2016/10/25 19:32:10 UTC
qpid-dispatch git commit: DISPATCH-543 Request only info needed to
calculate the topology so the graph can be drawn quicker
Repository: qpid-dispatch
Updated Branches:
refs/heads/master 6e051ce75 -> d2c326ac3
DISPATCH-543 Request only info needed to calculate the topology so the graph can be drawn quicker
Project: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/commit/d2c326ac
Tree: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/tree/d2c326ac
Diff: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/diff/d2c326ac
Branch: refs/heads/master
Commit: d2c326ac35899fa3fba75808270169b6083293f2
Parents: 6e051ce
Author: Ernest Allen <ea...@redhat.com>
Authored: Tue Oct 25 15:31:52 2016 -0400
Committer: Ernest Allen <ea...@redhat.com>
Committed: Tue Oct 25 15:31:52 2016 -0400
----------------------------------------------------------------------
console/stand-alone/plugin/js/dispatchPlugin.js | 1 +
console/stand-alone/plugin/js/qdrService.js | 112 ++--
console/stand-alone/plugin/js/qdrSettings.js | 1 +
console/stand-alone/plugin/js/qdrTopology.js | 549 ++++++++++---------
4 files changed, 359 insertions(+), 304 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/d2c326ac/console/stand-alone/plugin/js/dispatchPlugin.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/dispatchPlugin.js b/console/stand-alone/plugin/js/dispatchPlugin.js
index a565768..f3168c3 100644
--- a/console/stand-alone/plugin/js/dispatchPlugin.js
+++ b/console/stand-alone/plugin/js/dispatchPlugin.js
@@ -202,6 +202,7 @@ var QDR = (function(QDR) {
})
})
QDR.log.debug("requesting a topology")
+ QDRService.setUpdateEntities([])
QDRService.topology.get()
})
});
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/d2c326ac/console/stand-alone/plugin/js/qdrService.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/qdrService.js b/console/stand-alone/plugin/js/qdrService.js
index 68001aa..ed1d2fc 100644
--- a/console/stand-alone/plugin/js/qdrService.js
+++ b/console/stand-alone/plugin/js/qdrService.js
@@ -28,7 +28,7 @@ var QDR = (function(QDR) {
rhea: require("rhea"),
- timeout: 4, // seconds to wait before assuming a request has failed
+ timeout: 10, // seconds to wait before assuming a request has failed
updateInterval: 2000, // milliseconds between background updates
connectActions: [],
disconnectActions: [],
@@ -124,7 +124,7 @@ console.dump(e)
self.gotTopology = true;
//$rootScope.$apply();
} else {
- QDR.log.debug("topology model was just updated");
+ //QDR.log.debug("topology model was just updated");
}
self.executeUpdatedActions();
@@ -347,6 +347,12 @@ console.dump(e)
return identity
},
+ queueDepth: function () {
+ var qdepth = self.maxCorrelatorDepth - self.correlator.depth()
+ if (qdepth <= 0)
+ qdepth = 1;
+ return qdepth;
+ },
// check if all nodes have this entity. if not, get them
initEntity: function (entity, callback) {
var callNeeded = Object.keys(self.topology._nodeInfo).some( function (node) {
@@ -363,10 +369,7 @@ console.dump(e)
if (Object.prototype.toString.call(entities) !== '[object Array]') {
entities = [entities]
}
- var qdepth = self.maxCorrelatorDepth - self.correlator.depth()
- if (qdepth <= 0)
- qdepth = 1;
- var q = queue(qdepth)
+ var q = queue(self.queueDepth())
for (node in self.topology._nodeInfo) {
for (var i=0; i<entities.length; ++i) {
var entity = entities[i]
@@ -378,6 +381,33 @@ console.dump(e)
})
},
+ // enusre all the topology nones have all these entities
+ ensureAllEntities: function (entityAttribs, callback) {
+ self.ensureEntities(Object.keys(self.topology._nodeInfo), entityAttribs, callback)
+ },
+
+ // ensure these nodes have all these entities. don't fetch unless forced to
+ ensureEntities: function (nodes, entityAttribs, callback) {
+ if (Object.prototype.toString.call(entityAttribs) !== '[object Array]') {
+ entityAttribs = [entityAttribs]
+ }
+ if (Object.prototype.toString.call(nodes) !== '[object Array]') {
+ nodes = [nodes]
+ }
+ var q = queue(self.queueDepth())
+ for (var n=0; n<nodes.length; ++n) {
+ for (var i=0; i<entityAttribs.length; ++i) {
+ var ea = entityAttribs[i]
+ // if we don'e already have the entity or we want to force a refresh
+ if (!self.topology._nodeInfo[nodes[n]][ea.entity] || ea.force)
+ q.defer(self.ensureNodeInfo, nodes[n], ea.entity, ea.attrs || [], q)
+ }
+ }
+ q.await(function (error) {
+ callback();
+ })
+ },
+
setUpdateEntities: function (entities) {
self.topology._autoUpdatedEntities = entities
},
@@ -404,7 +434,7 @@ console.dump(e)
_waitTimer: null,
_getTimer: null,
_autoUpdatedEntities: [],
- _lastRequestTime: null,
+ q: null,
nodeInfo: function() {
return self.topology._nodeInfo
@@ -413,8 +443,10 @@ console.dump(e)
get: function() {
if (self.topology._gettingTopo) {
QDR.log.debug("asked to get topology but was already getting it")
- return;
+ if (self.topology.q)
+ self.topology.q.abort()
}
+ self.topology.q = null
if (!self.connected) {
QDR.log.debug("topology get failed because !self.connected")
return;
@@ -453,23 +485,21 @@ console.dump(e)
}
// also refresh any entities that were requested
- var qdepth = self.maxCorrelatorDepth - self.correlator.depth()
- if (qdepth <= 0)
- qdepth = 1;
- q = queue(qdepth)
- for (node in self.topology._nodeInfo) {
- for (var i=0; i<self.topology._autoUpdatedEntities.length; ++i) {
- var entity = self.topology._autoUpdatedEntities[i]
- self.topology.expect(node, entity)
- q.defer(self.ensureNodeInfo, node, entity, [], q)
+ self.topology.q = queue(self.queueDepth())
+ for (var i=0; i<self.topology._autoUpdatedEntities.length; ++i) {
+ var entity = self.topology._autoUpdatedEntities[i]
+ //QDR.log.debug("queuing requests for all nodes for " + entity)
+ for (node in self.topology._nodeInfo) {
+ //self.topology.expect(node, entity)
+ self.topology.q.defer(self.ensureNodeInfo, node, entity, [], self.topology.q)
}
}
- self.topology._lastRequestTime = Date.now()
- self.topology._waitTimer = setTimeout(self.topology.timedOut, self.timeout * 1000, q);
- q.await(function (error) {
-QDR.log.debug("Done awaiting for topology. error is " + error)
- if (!error)
- self.topology.ondone();
+ clearTimeout(self.topology._waitTimer)
+ self.topology._waitTimer = setTimeout(self.topology.timedOut, self.timeout * 1000, self.topology.q);
+ self.topology.q.await(function (error) {
+//QDR.log.debug("Done awaiting for topology. error is " + error)
+ self.topology._gettingTopo = false;
+ self.topology.ondone(error)
})
};
});
@@ -488,11 +518,11 @@ QDR.log.debug("Done awaiting for topology. error is " + error)
// note: can't use 'this' in a timeout handler
self.topology.miniDump("state at timeout");
// check if _nodeInfo is consistent
- if (self.topology.isConsistent()) {
+ //if (self.topology.isConsistent()) {
q.abort()
- self.topology.ondone();
- return;
- }
+ //self.topology.ondone();
+ // return;
+ //}
self.topology.onerror(Error("management responses are not consistent"));
},
isConsistent: function() {
@@ -524,7 +554,7 @@ QDR.log.debug("Done awaiting for topology. error is " + error)
return true;
},
- addNodeInfo: function(id, entity, values) {
+ addNodeInfo: function(id, entity, values, q) {
if (self.topology._waitTimer)
clearTimeout(self.topology._waitTimer)
self.topology._waitTimer = setTimeout(self.topology.timedOut, self.timeout * 1000, q);
@@ -559,13 +589,14 @@ QDR.log.debug("Done awaiting for topology. error is " + error)
if (self.topology._expected[id].indexOf(key) == -1)
self.topology._expected[id].push(key);
},
- ondone: function() {
+ ondone: function(waserror) {
+ clearTimeout(self.topology._getTimer);
clearTimeout(self.topology._waitTimer);
self.topology._waitTimer = null;
- self.topology._gettingTopo = false;
if (self.updating)
self.topology._getTimer = setTimeout(self.topology.get, self.updateInterval);
- self.notifyTopologyDone();
+ if (!waserror)
+ self.notifyTopologyDone();
},
dump: function(prefix) {
if (prefix)
@@ -589,8 +620,7 @@ QDR.log.debug("Done awaiting for topology. error is " + error)
onerror: function(err) {
self.topology._gettingTopo = false;
QDR.log.debug("Err:" + err);
- self.executeDisconnectActions();
-
+ //self.executeDisconnectActions();
}
},
@@ -607,22 +637,12 @@ QDR.log.debug("Done awaiting for topology. error is " + error)
}, ret.error);
},
- makeMgmtCalls: function(id) {
-QDR.log.debug("called makeMgmtCalls with id of " + id)
- var keys = [".router", ".connection", ".container", ".router.node", ".listener", ".router.link"];
- $.each(keys, function(i, key) {
- self.topology.expect(id, key);
- self.getNodeInfo(id, key, [], self.topology.addNodeInfo);
- });
- },
-
// should only be called from a q.defer() statement
ensureNodeInfo: function (nodeId, entity, attrs, q, callback) {
- QDR.log.debug("queuing request for " + nodeId + " " + entity)
+ //QDR.log.debug("queuing request for " + nodeId + " " + entity)
self.getNodeInfo(nodeId, entity, attrs, function (nodeName, dotentity, response) {
- QDR.log.debug("got response for " + nodeId + " " + entity)
- self.topology.addNodeInfo(nodeName, dotentity, response)
- //self.topology._nodeInfo[nodeName][dotentity] = response
+ //QDR.log.debug("got response for " + nodeId + " " + entity)
+ self.topology.addNodeInfo(nodeName, dotentity, response, q)
callback(null)
})
return {
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/d2c326ac/console/stand-alone/plugin/js/qdrSettings.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/qdrSettings.js b/console/stand-alone/plugin/js/qdrSettings.js
index f81818b..e33be52 100644
--- a/console/stand-alone/plugin/js/qdrSettings.js
+++ b/console/stand-alone/plugin/js/qdrSettings.js
@@ -106,6 +106,7 @@ QDR.log.debug(QDR.pluginRoot + "/" + goto)
})
})
QDR.log.debug("requesting a topology")
+ QDRService.setUpdateEntities([])
QDRService.topology.get()
})
});
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/d2c326ac/console/stand-alone/plugin/js/qdrTopology.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/qdrTopology.js b/console/stand-alone/plugin/js/qdrTopology.js
index 44e9d02..36f9292 100644
--- a/console/stand-alone/plugin/js/qdrTopology.js
+++ b/console/stand-alone/plugin/js/qdrTopology.js
@@ -42,6 +42,7 @@ var QDR = (function(QDR) {
};
$scope.form = ''
$scope.$on('showEntityForm', function(event, args) {
+QDR.log.debug("showEntityForm")
var attributes = args.attributes;
var entityTypes = QDRService.schema.entityTypes[args.entity].attributes;
attributes.forEach(function(attr) {
@@ -120,6 +121,7 @@ var QDR = (function(QDR) {
$scope.linkData = obj.entity.linkData;
$scope.connectionId = obj.entity.connectionId;
var visibleLen = Math.min(obj.entity.linkData.length, 10)
+ QDR.log.debug("visibleLen is " + visibleLen)
var left = parseInt(d3.select('#multiple_details').style("left"))
var detailsDiv = d3.select('#link_details')
detailsDiv
@@ -557,9 +559,11 @@ var QDR = (function(QDR) {
}
}
- var getLinkDir = function (connection, onode) {
- // find all the liinks associated with this connection on this router(id)
+ var getLinkDir = function (id, connection, onode) {
var links = onode[".router.link"]
+ if (!links) {
+ return "unknown"
+ }
var inCount = 0, outCount = 0
links.results.forEach( function (linkResult) {
var link = QDRService.flatten(links.attributeNames, linkResult)
@@ -577,6 +581,7 @@ var QDR = (function(QDR) {
return "out"
return connection.dir
}
+
var savePositions = function () {
d3.selectAll('#SVG_ID circle.inter-router')
.each( function (d) {
@@ -587,65 +592,9 @@ var QDR = (function(QDR) {
});
})
}
- // initialize the nodes and links array from the QDRService.topology._nodeInfo object
- var initForceGraph = function() {
- nodes = [];
- links = [];
-
- var oldSelectedNode = selected_node
- var oldMouseoverNode = mouseover_node
- mouseover_node = null;
- selected_node = null;
- selected_link = null;
-
- savePositions();
- d3.select("#SVG_ID").remove();
- svg = d3.select('#topology')
- .append('svg')
- .attr("id", "SVG_ID")
- .attr('width', width)
- .attr('height', height)
- .on("contextmenu", function(d) {
- if (d3.event.defaultPrevented)
- return;
- d3.event.preventDefault();
- if ($scope.addingNode.step != 0)
- return;
- if (d3.select('#svg_context_menu').style('display') !== 'block')
- $(document).click();
- d3.select('#svg_context_menu')
- .style('left', (mouseX + $(document).scrollLeft()) + "px")
- .style('top', (mouseY + $(document).scrollTop()) + "px")
- .style('display', 'block');
- })
- .on('click', function(d) {
- removeCrosssection()
- });
-
- $(document).keyup(function(e) {
- if (e.keyCode === 27) {
- removeCrosssection()
- }
- });
-
- // the legend
- d3.select("#svg_legend svg").remove();
- lsvg = d3.select("#svg_legend")
- .append('svg')
- .attr('id', 'svglegend')
- lsvg = lsvg.append('svg:g')
- .attr('transform', 'translate(' + (radii['inter-router'] + 2) + ',' + (radii['inter-router'] + 2) + ')')
- .selectAll('g');
-
- // mouse event vars
- mousedown_link = null;
- mousedown_node = null;
- mouseup_node = null;
- // initialize the list of nodes
+ var initializeNodes = function (nodeInfo, nodeCount, height) {
var yInit = 10;
- var nodeInfo = QDRService.topology.nodeInfo();
- var nodeCount = Object.keys(nodeInfo).length;
for (var id in nodeInfo) {
var name = QDRService.nameFromId(id);
// if we have any new nodes, animate the force graph to position them
@@ -657,15 +606,16 @@ var QDR = (function(QDR) {
y: 200 + yInit,
fixed: false
};
+ yInit *= -1;
}
if (position.y > height)
position.y = 200 - yInit;
nodes.push(aNode(id, name, "inter-router", nodeInfo, nodes.length, position.x, position.y, undefined, position.fixed));
- yInit *= -1;
//QDR.log.debug("adding node " + nodes.length-1);
}
+ }
- // initialize the list of links
+ var initializeLinks = function (nodeInfo, unknowns) {
var source = 0;
var client = 1;
for (var id in nodeInfo) {
@@ -682,7 +632,7 @@ var QDR = (function(QDR) {
var dir = connection.dir
if (role == "inter-router") {
var connId = connection.container
- var target = getContainerIndex(connId);
+ var target = getContainerIndex(connId, nodeInfo);
if (target >= 0)
getLink(source, target, dir);
} else if (role == "normal" || role == "on-demand") {
@@ -705,25 +655,28 @@ var QDR = (function(QDR) {
var node = aNode(id, name, role, nodeInfo, nodes.length, position.x, position.y, j, position.fixed, properties)
var nodeType = QDRService.isAConsole(properties, connection.identity, role, node.key) ? "console" : "client"
if (role === 'normal') {
- var cdir = getLinkDir(connection, onode)
- node.user = connection.user
- node.isEncrypted = connection.isEncrypted
- node.host = connection.host
- node.connectionId = connection.identity
- node.cdir = cdir
- // determine arrow direction by using the link directions
- if (!normalsParent[nodeType+cdir]) {
- normalsParent[nodeType+cdir] = node;
- nodes.push(node);
- node.normals = [node];
- // now add a link
- getLink(source, nodes.length - 1, cdir, "small");
- client++;
+ var cdir = getLinkDir(id, connection, onode)
+ if (cdir !== 'unknown') {
+ node.user = connection.user
+ node.isEncrypted = connection.isEncrypted
+ node.host = connection.host
+ node.connectionId = connection.identity
+ node.cdir = cdir
+ // determine arrow direction by using the link directions
+ if (!normalsParent[nodeType+cdir]) {
+ normalsParent[nodeType+cdir] = node;
+ nodes.push(node);
+ node.normals = [node];
+ // now add a link
+ getLink(source, nodes.length - 1, cdir, "small");
+ client++;
+ } else {
+ normalsParent[nodeType+cdir].normals.push(node)
+ }
} else {
- normalsParent[nodeType+cdir].normals.push(node)
+ unknowns.push(node)
}
} else {
-//QDR.log.debug("on-demand client found")
nodes.push(node)
// now add a link
getLink(source, nodes.length - 1, dir, "small");
@@ -733,6 +686,71 @@ var QDR = (function(QDR) {
}
source++;
}
+ }
+
+ // initialize the nodes and links array from the QDRService.topology._nodeInfo object
+ var initForceGraph = function() {
+ nodes = [];
+ links = [];
+
+ var oldSelectedNode = selected_node
+ var oldMouseoverNode = mouseover_node
+ mouseover_node = null;
+ selected_node = null;
+ selected_link = null;
+
+ savePositions();
+ d3.select("#SVG_ID").remove();
+ svg = d3.select('#topology')
+ .append('svg')
+ .attr("id", "SVG_ID")
+ .attr('width', width)
+ .attr('height', height)
+ .on("contextmenu", function(d) {
+ if (d3.event.defaultPrevented)
+ return;
+ d3.event.preventDefault();
+ if ($scope.addingNode.step != 0)
+ return;
+ if (d3.select('#svg_context_menu').style('display') !== 'block')
+ $(document).click();
+ d3.select('#svg_context_menu')
+ .style('left', (mouseX + $(document).scrollLeft()) + "px")
+ .style('top', (mouseY + $(document).scrollTop()) + "px")
+ .style('display', 'block');
+ })
+ .on('click', function(d) {
+ removeCrosssection()
+ });
+
+ $(document).keyup(function(e) {
+ if (e.keyCode === 27) {
+ removeCrosssection()
+ }
+ });
+
+ // the legend
+ d3.select("#svg_legend svg").remove();
+ lsvg = d3.select("#svg_legend")
+ .append('svg')
+ .attr('id', 'svglegend')
+ lsvg = lsvg.append('svg:g')
+ .attr('transform', 'translate(' + (radii['inter-router'] + 2) + ',' + (radii['inter-router'] + 2) + ')')
+ .selectAll('g');
+
+ // mouse event vars
+ mousedown_link = null;
+ mousedown_node = null;
+ mouseup_node = null;
+
+ // initialize the list of nodes
+ var nodeInfo = QDRService.topology.nodeInfo();
+ var nodeCount = Object.keys(nodeInfo).length;
+ initializeNodes(nodeInfo, nodeCount, height)
+
+ // initialize the list of links
+ var unknowns = []
+ initializeLinks(nodeInfo, unknowns)
$scope.schema = QDRService.schema;
// init D3 force layout
@@ -744,13 +762,13 @@ var QDR = (function(QDR) {
if (d.target.nodeType === 'inter-router')
return 80
if (d.target.cdir === 'both')
- return 70
- return 70
+ return 25
+ return 15
})
.charge(function(d) {
- return (d.nodeType === 'inter-router') ? -3000 : -300
+ return (d.nodeType === 'inter-router') ? -3000 : -750
})
- .friction(.10)
+ .friction(.50)
.gravity(0.0001)
.on('tick', tick)
.start()
@@ -821,94 +839,93 @@ var QDR = (function(QDR) {
d3.selectAll('circle.inter-router').each(function (d) {
if (d.key === oldMouseoverNode.key) {
mouseover_node = d
- QDRService.initEntity(".router.node", function () {
+ QDRService.ensureAllEntities([{entity: ".router.node", attrs: ["id","nextHop"]}], function () {
nextHop(selected_node, d);
restart();
})
}
})
}
-
- setTimeout(function() {
+ setTimeout(function () {
updateForm(Object.keys(QDRService.topology.nodeInfo())[0], 'router', 0);
- }, 10)
+ })
+
+ // if any clients don't yet have link directions, get the links for those nodes and restart the graph
+ var unknownNodes = unknowns.map( function (un) {
+ return un.key
+ })
+ if (unknownNodes.length) {
+ QDRService.ensureEntities(unknownNodes, {entity: ".router.link"}, function () {
+ // now that all nodes with clients have link info, update the nodes
+ animate = true;
+ initForceGraph();
+ })
+ }
}
function updateForm(key, entity, resultIndex) {
var nodeInfo = QDRService.topology.nodeInfo();
- var onode = nodeInfo[key]
- if (onode) {
- var nodeResults = onode['.' + entity].results[resultIndex]
- var nodeAttributes = onode['.' + entity].attributeNames
- var attributes = nodeResults.map(function(row, i) {
- return {
- attributeName: nodeAttributes[i],
- attributeValue: row
- }
+ if (key in nodeInfo) {
+ QDRService.ensureEntities(key, [
+ {entity: '.'+entity},
+ {entity: '.listener', attrs: ["role", "port"]}], function () {
+ var onode = nodeInfo[key]
+ var nodeResults = onode['.' + entity].results[resultIndex]
+ var nodeAttributes = onode['.' + entity].attributeNames
+ var attributes = nodeResults.map(function(row, i) {
+ return {
+ attributeName: nodeAttributes[i],
+ attributeValue: row
+ }
+ })
+ // sort by attributeName
+ attributes.sort(function(a, b) {
+ return a.attributeName.localeCompare(b.attributeName)
})
- // sort by attributeName
- attributes.sort(function(a, b) {
- return a.attributeName.localeCompare(b.attributeName)
- })
- // move the Name first
- var nameIndex = attributes.findIndex(function(attr) {
- return attr.attributeName === 'name'
- })
- if (nameIndex >= 0)
- attributes.splice(0, 0, attributes.splice(nameIndex, 1)[0]);
-
- // get the list of ports this router is listening on
- if (entity === 'router') {
- var listeners = onode['.listener'].results;
- var listenerAttributes = onode['.listener'].attributeNames;
- var normals = listeners.filter(function(listener) {
- return QDRService.valFor(listenerAttributes, listener, 'role') === 'normal';
+ // move the Name first
+ var nameIndex = attributes.findIndex(function(attr) {
+ return attr.attributeName === 'name'
})
- var ports = []
- normals.forEach(function(normalListener) {
- ports.push(QDRService.valFor(listenerAttributes, normalListener, 'port'))
+ if (nameIndex >= 0)
+ attributes.splice(0, 0, attributes.splice(nameIndex, 1)[0]);
+
+ // get the list of ports this router is listening on
+ if (entity === 'router') {
+ var listeners = onode['.listener'].results;
+ var listenerAttributes = onode['.listener'].attributeNames;
+ var normals = listeners.filter(function(listener) {
+ return QDRService.valFor(listenerAttributes, listener, 'role') === 'normal';
})
- // add as 2nd row
- if (ports.length) {
- attributes.splice(1, 0, {
- attributeName: 'Listening on',
- attributeValue: ports,
- description: 'The port on which this router is listening for connections'
- });
+ var ports = []
+ normals.forEach(function(normalListener) {
+ ports.push(QDRService.valFor(listenerAttributes, normalListener, 'port'))
+ })
+ // add as 2nd row
+ if (ports.length) {
+ attributes.splice(1, 0, {
+ attributeName: 'Listening on',
+ attributeValue: ports,
+ description: 'The port on which this router is listening for connections'
+ });
+ }
}
- }
- $scope.$broadcast('showEntityForm', {
- entity: entity,
- attributes: attributes
+ $scope.$broadcast('showEntityForm', {
+ entity: entity,
+ attributes: attributes
+ })
+ if (!$scope.$$phase) $scope.$apply()
})
}
- if (!$scope.$$phase) $scope.$apply()
}
- function getContainerIndex(_id) {
+ function getContainerIndex(_id, nodeInfo) {
var nodeIndex = 0;
- var nodeInfo = QDRService.topology.nodeInfo();
for (var id in nodeInfo) {
- var node = nodeInfo[id]['.router'];
- // there should be only one router entity for each node, so using results[0] should be fine
- if (QDRService.valFor(node.attributeNames, node.results[0], "id") === _id)
- return nodeIndex;
- if (QDRService.valFor(node.attributeNames, node.results[0], "routerId") === _id)
+ if (QDRService.nameFromId(id) === _id)
return nodeIndex;
- nodeIndex++
- }
- // there was no router.id that matched, check deprecated router.routerId
- nodeIndex = 0;
- for (var id in nodeInfo) {
- var node = nodeInfo[id]['.container'];
- if (node) {
- if (QDRService.valFor(node.attributeNames, node.results[0], "containerName") === _id)
- return nodeIndex;
- }
- nodeIndex++
+ ++nodeIndex;
}
- //QDR.log.warn("unable to find containerIndex for " + _id);
return -1;
}
@@ -1335,7 +1352,7 @@ var QDR = (function(QDR) {
svgg.transition().attr("transform", "translate(2,2) scale(1)")
}
- QDRService.loadEntity(".router.link", showCrosssection)
+ QDRService.initEntity(".router.link", showCrosssection)
})
// remove old links
@@ -1446,7 +1463,7 @@ var QDR = (function(QDR) {
}
clerAllHighlights()
// we need .router.node info to highlight hops
- QDRService.initEntity(".router.node", function () {
+ QDRService.ensureAllEntities([{entity: ".router.node", attrs: ["id","nextHop"]}], function () {
mouseover_node = d // save this node in case the topology changes so we can restore the highlights
nextHop(selected_node, d);
restart();
@@ -1663,13 +1680,18 @@ var QDR = (function(QDR) {
node.cdir = "out"
legendNodes.push(node)
}
+ if (!svg.selectAll('circle.client.inout').empty()) {
+ var node = aNode("Sender/Receiver", "", "normal", undefined, 4, 0, 0, 0, false, {})
+ node.cdir = "both"
+ legendNodes.push(node)
+ }
if (!svg.selectAll('circle.qpid-cpp').empty()) {
- legendNodes.push(aNode("Qpid broker", "", "on-demand", undefined, 4, 0, 0, 0, false, {
+ legendNodes.push(aNode("Qpid broker", "", "on-demand", undefined, 5, 0, 0, 0, false, {
product: 'qpid-cpp'
}))
}
if (!svg.selectAll('circle.artemis').empty()) {
- legendNodes.push(aNode("Artemis broker", "", "on-demand", undefined, 5, 0, 0, 0, false, {}))
+ legendNodes.push(aNode("Artemis broker", "", "on-demand", undefined, 6, 0, 0, 0, false, {}))
}
lsvg = lsvg.data(legendNodes, function(d) {
return d.id;
@@ -1721,118 +1743,123 @@ var QDR = (function(QDR) {
}
var startUpdateConnectionsGrid = function(d) {
+ // called after each topology update
var extendConnections = function() {
- $scope.multiData = []
- var normals = d.normals;
- // find updated normals for d
- d3.selectAll('.normal')
- .each(function(newd) {
- if (newd.id == d.id && newd.name == d.name) {
- normals = newd.normals;
- }
- });
- if (normals) {
- normals.forEach(function(n) {
- var nodeInfo = QDRService.topology.nodeInfo();
- var links = nodeInfo[n.key]['.router.link'];
- var linkTypeIndex = links.attributeNames.indexOf('linkType');
- var connectionIdIndex = links.attributeNames.indexOf('connectionId');
- n.linkData = [];
- links.results.forEach(function(link) {
- if (link[linkTypeIndex] === 'endpoint' && link[connectionIdIndex] === n.connectionId) {
- var l = {};
- l.owningAddr = QDRService.valFor(links.attributeNames, link, 'owningAddr');
- l.dir = QDRService.valFor(links.attributeNames, link, 'linkDir');
- if (l.owningAddr && l.owningAddr.length > 2)
- if (l.owningAddr[0] === 'M')
- l.owningAddr = l.owningAddr.substr(2)
- else
- l.owningAddr = l.owningAddr.substr(1)
-
- l.deliveryCount = QDRService.pretty(QDRService.valFor(links.attributeNames, link, 'deliveryCount'));
- l.uncounts = QDRService.pretty(QDRService.valFor(links.attributeNames, link, 'undeliveredCount') +
- QDRService.valFor(links.attributeNames, link, 'unsettledCount'))
- //l.undeliveredCount = QDRService.pretty(QDRService.valFor(links.attributeNames, link, 'undeliveredCount'));
- //l.unsettledCount = QDRService.pretty(QDRService.valFor(links.attributeNames, link, 'unsettledCount'));
- l.adminStatus = QDRService.valFor(links.attributeNames, link, 'adminStatus');
- l.operStatus = QDRService.valFor(links.attributeNames, link, 'operStatus');
- l.identity = QDRService.valFor(links.attributeNames, link, 'identity')
- l.connectionId = QDRService.valFor(links.attributeNames, link, 'connectionId')
- l.nodeId = n.key
- l.type = QDRService.valFor(links.attributeNames, link, 'type')
- l.name = QDRService.valFor(links.attributeNames, link, 'name')
-
- // TODO: remove this fake quiescing/reviving logic when the routers do the work
- initConnState(n.connectionId)
- if ($scope.quiesceState[n.connectionId].linkStates[l.identity])
- l.adminStatus = $scope.quiesceState[n.connectionId].linkStates[l.identity];
- if ($scope.quiesceState[n.connectionId].state == 'quiescing') {
- if (l.adminStatus === 'enabled') {
- // 25% chance of switching
- var chance = Math.floor(Math.random() * 2);
- if (chance == 1) {
- l.adminStatus = 'disabled';
- $scope.quiesceState[n.connectionId].linkStates[l.identity] = 'disabled';
+ // force a fetch of the links for this node
+ QDRService.ensureEntities(d.key, {entity: ".router.link", force: true}, function () {
+ // the links for this node are now available
+ $scope.multiData = []
+ var normals = d.normals;
+ // find updated normals for d
+ d3.selectAll('.normal')
+ .each(function(newd) {
+ if (newd.id == d.id && newd.name == d.name) {
+ normals = newd.normals;
+ }
+ });
+ if (normals) {
+ normals.forEach(function(n) {
+ var nodeInfo = QDRService.topology.nodeInfo();
+ var links = nodeInfo[n.key]['.router.link'];
+ var linkTypeIndex = links.attributeNames.indexOf('linkType');
+ var connectionIdIndex = links.attributeNames.indexOf('connectionId');
+ n.linkData = [];
+ links.results.forEach(function(link) {
+ if (link[linkTypeIndex] === 'endpoint' && link[connectionIdIndex] === n.connectionId) {
+ var l = {};
+ l.owningAddr = QDRService.valFor(links.attributeNames, link, 'owningAddr');
+ l.dir = QDRService.valFor(links.attributeNames, link, 'linkDir');
+ if (l.owningAddr && l.owningAddr.length > 2)
+ if (l.owningAddr[0] === 'M')
+ l.owningAddr = l.owningAddr.substr(2)
+ else
+ l.owningAddr = l.owningAddr.substr(1)
+
+ l.deliveryCount = QDRService.pretty(QDRService.valFor(links.attributeNames, link, 'deliveryCount'));
+ l.uncounts = QDRService.pretty(QDRService.valFor(links.attributeNames, link, 'undeliveredCount') +
+ QDRService.valFor(links.attributeNames, link, 'unsettledCount'))
+ //l.undeliveredCount = QDRService.pretty(QDRService.valFor(links.attributeNames, link, 'undeliveredCount'));
+ //l.unsettledCount = QDRService.pretty(QDRService.valFor(links.attributeNames, link, 'unsettledCount'));
+ l.adminStatus = QDRService.valFor(links.attributeNames, link, 'adminStatus');
+ l.operStatus = QDRService.valFor(links.attributeNames, link, 'operStatus');
+ l.identity = QDRService.valFor(links.attributeNames, link, 'identity')
+ l.connectionId = QDRService.valFor(links.attributeNames, link, 'connectionId')
+ l.nodeId = n.key
+ l.type = QDRService.valFor(links.attributeNames, link, 'type')
+ l.name = QDRService.valFor(links.attributeNames, link, 'name')
+
+ // TODO: remove this fake quiescing/reviving logic when the routers do the work
+ initConnState(n.connectionId)
+ if ($scope.quiesceState[n.connectionId].linkStates[l.identity])
+ l.adminStatus = $scope.quiesceState[n.connectionId].linkStates[l.identity];
+ if ($scope.quiesceState[n.connectionId].state == 'quiescing') {
+ if (l.adminStatus === 'enabled') {
+ // 25% chance of switching
+ var chance = Math.floor(Math.random() * 2);
+ if (chance == 1) {
+ l.adminStatus = 'disabled';
+ $scope.quiesceState[n.connectionId].linkStates[l.identity] = 'disabled';
+ }
}
}
- }
- if ($scope.quiesceState[n.connectionId].state == 'reviving') {
- if (l.adminStatus === 'disabled') {
- // 25% chance of switching
- var chance = Math.floor(Math.random() * 2);
- if (chance == 1) {
- l.adminStatus = 'enabled';
- $scope.quiesceState[n.connectionId].linkStates[l.identity] = 'enabled';
+ if ($scope.quiesceState[n.connectionId].state == 'reviving') {
+ if (l.adminStatus === 'disabled') {
+ // 25% chance of switching
+ var chance = Math.floor(Math.random() * 2);
+ if (chance == 1) {
+ l.adminStatus = 'enabled';
+ $scope.quiesceState[n.connectionId].linkStates[l.identity] = 'enabled';
+ }
}
}
- }
- QDR.log.debug("pushing link state for " + l.owningAddr + " status: " + l.adminStatus)
+ QDR.log.debug("pushing link state for " + l.owningAddr + " status: " + l.adminStatus)
- n.linkData.push(l)
- }
+ n.linkData.push(l)
+ }
+ })
+ $scope.multiData.push(n)
+ if (n.connectionId == $scope.connectionId)
+ $scope.linkData = n.linkData;
+ initConnState(n.connectionId)
+ $scope.multiDetails.updateState(n)
})
- $scope.multiData.push(n)
- if (n.connectionId == $scope.connectionId)
- $scope.linkData = n.linkData;
- initConnState(n.connectionId)
- $scope.multiDetails.updateState(n)
- })
- }
- $scope.$apply();
+ }
+ $scope.$apply();
- d3.select('#multiple_details')
- .style({
- height: ((normals.length + 1) * 30) + 40 + "px",
- 'overflow-y': normals.length > 10 ? 'scroll' : 'hidden'
- })
+ d3.select('#multiple_details')
+ .style({
+ height: ((normals.length + 1) * 30) + 40 + "px",
+ 'overflow-y': normals.length > 10 ? 'scroll' : 'hidden'
+ })
+ })
}
-
- QDRService.addUpdateEntity(".router.link")
- QDRService.loadEntity(".router.link", function () {
- QDRService.addUpdatedAction("normalsStats", extendConnections)
- extendConnections();
- clearPopups();
- var display = 'block'
- var left = mouseX + $(document).scrollLeft()
- if (d.normals.length === 1) {
- display = 'none'
- left = left - 30;
- mouseY = mouseY - 20
- }
- d3.select('#multiple_details')
- .style({
- display: display,
- opacity: 1,
- left: (mouseX + $(document).scrollLeft()) + "px",
- top: (mouseY + $(document).scrollTop()) + "px"
- })
- if (d.normals.length === 1) {
- // simulate a click on the connection to popup the link details
+ // register a notification function for when the topology is updated
+ QDRService.addUpdatedAction("normalsStats", extendConnections)
+ // call the function that gets the links right now
+ extendConnections();
+ clearPopups();
+ var display = 'block'
+ var left = mouseX + $(document).scrollLeft()
+ if (d.normals.length === 1) {
+ display = 'none'
+ left = left - 30;
+ mouseY = mouseY - 20
+ }
+ d3.select('#multiple_details')
+ .style({
+ display: display,
+ opacity: 1,
+ left: (mouseX + $(document).scrollLeft()) + "px",
+ top: (mouseY + $(document).scrollTop()) + "px"
+ })
+ if (d.normals.length === 1) {
+ // simulate a click on the connection to popup the link details
+ QDRService.ensureEntities(d.key, {entity: ".router.link", force: true}, function () {
$scope.multiDetails.showLinksList({
entity: d
})
- }
- })
+ })
+ }
}
var stopUpdateConnectionsGrid = function() {
QDRService.delUpdateEntity([".router.link"])
@@ -1941,29 +1968,33 @@ var QDR = (function(QDR) {
// the scope
$scope.$on("$destroy", function(event) {
//QDR.log.debug("scope on destroy");
+ savePositions();
QDRService.stopUpdating();
+ QDRService.delUpdatedAction("normalsStats");
QDRService.delUpdatedAction("topology");
d3.select("#SVG_ID").remove();
window.removeEventListener('resize', resize);
});
function handleInitialUpdate() {
- QDRService.delUpdatedAction("topologyInitialized")
- // now we only need to update connections during steady-state
+ // we only need to update connections during steady-state
QDRService.setUpdateEntities([".connection"])
// we currently have all entities available on all routers
saveChanged();
animate = true;
initForceGraph();
- QDRService.initEntity(".router.node", function () {})
+ // after the graph is displayed fetch all .router.node info. This is done so highlighting between nodes
+ // doesn't incur a delay
+ QDRService.ensureAllEntities([{entity: ".router.node", attrs: ["id","nextHop"]}], function () {})
+ // call this function every time a background update is done
QDRService.addUpdatedAction("topology", function() {
var changed = hasChanged()
- // there is a new node, we need to get all of it's entities before drawing the svg
+ // there is a new node, we need to get all of it's entities before drawing the graph
if (changed > 0) {
QDRService.delUpdatedAction("topology")
setupInitialUpdate()
} else if (changed === -1) {
- // we lost a node, we can draw the new svg immediately
+ // we lost a node (or a client), we can draw the new svg immediately
saveChanged();
animate = true;
initForceGraph();
@@ -1975,9 +2006,11 @@ var QDR = (function(QDR) {
}
function setupInitialUpdate() {
-//QDR.log.debug("setting up initial update for topology. requesting all entities for all routers")
- QDRService.setUpdateEntities([".connection", ".router.link", ".router", ".listener"])
- QDRService.addUpdatedAction("topologyInitialized", handleInitialUpdate)
+ // make sure all router nodes have .connection info. if not then fetch any missing info
+ QDRService.ensureAllEntities(
+ //[{entity: ".connection"}, {entity: ".router.link", attrs: ["linkType","connectionId","linkDir"]}],
+ [{entity: ".connection"}],
+ handleInitialUpdate)
}
setupInitialUpdate();
QDRService.startUpdating();
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org