Adds "client throughput" to the queue tree tab of circuit_queue

Also moves all the circuit graphs to use the same graphing
system as the other graphs on the plot.

FIXES #315
This commit is contained in:
Herbert Wolverson 2023-03-31 16:20:56 +00:00
parent 3bc2c16328
commit 9fce5d51de

View File

@ -95,7 +95,8 @@
</div>
<div class="col-sm-2">
<a href="#" class="btn btn-small btn-info" id="btnPause"><i class="fa fa-pause"></i> Pause</a>
<a href="#" class="btn btn-small btn-info" id="btnSlow"><i class="fa fa-hourglass"></i> Slow Mode</a>
<a href="#" class="btn btn-small btn-info" id="btnSlow"><i class="fa fa-hourglass"></i> Slow
Mode</a>
</div>
</div>
</div>
@ -394,7 +395,8 @@
{
margin: { l: 0, r: 0, b: 0, t: 0, pad: 4 },
yaxis: { automargin: true, title: "Bytes" },
xaxis: { automargin: true, title: "Time since now" } });
xaxis: { automargin: true, title: "Time since now" }
});
} else {
Plotly.redraw(graph, graphData);
}
@ -413,9 +415,11 @@
Plotly.newPlot(
graph,
graphData,
{ margin: { l: 8, r: 0, b: 0, t: 0, pad: 4 },
{
margin: { l: 8, r: 0, b: 0, t: 0, pad: 4 },
yaxis: { automargin: true, title: "log10(ms)", range: [-1.0, 1.0] },
xaxis: { automargin: true, title: "Time since now" } });
xaxis: { automargin: true, title: "Time since now" }
});
this.delaysPlotted = true;
} else {
Plotly.redraw(graph, graphData);
@ -572,15 +576,15 @@
}
}
plot() {
let graph = document.getElementById("throughputGraph");
plot(target) {
let graph = document.getElementById(target);
let graphData = [];
for (const ip in this.per_ip) {
graphData.push({ x: this.x_axis, y: this.y[ip], name: ip, mode: 'markers', type: 'scattergl', marker: { size: 3 } });
}
if (this.plotted == null) {
if (!this.hasOwnProperty("plotted" + target)) {
Plotly.newPlot(graph, graphData, { margin: { l: 0, r: 0, b: 0, t: 0, pad: 4 }, yaxis: { automargin: true, title: "Traffic (bits)" }, xaxis: { automargin: true, title: "Time since now" } });
this.plotted = true;
this["plotted" + target] = true;
} else {
Plotly.redraw(graph, graphData);
}
@ -616,13 +620,13 @@
tpData.ingest(ip, down, up);
}
tpData.prepare();
tpData.plot();
tpData.plot("throughputGraph");
tpData.plotQuantiles();
});
}
}
let funnels = new MultiRingBuffer(300);
let funnels = new ThroughputMonitor(300);
let rtts = {};
let circuitId = "";
let builtFunnelDivs = false;
@ -635,8 +639,24 @@
circuitId = encodeURI(id);
msgPackGet("/api/funnel_for_queue/" + circuitId, (data) => {
let html = "";
// Add the client on top
let row = "<div class='row row220'>";
row += "<div class='col-sm-12'>";
row += "<div class='card bg-light'>";
row += "<h5 class='card-title'><i class='fa fa-hourglass'></i> Client Throughput</h5>";
row += "<div id='tp_client' class='graph98 graph150'></div>";
row += "</div>";
row += "</div>";
row += "</div>";
html += row;
// Funnels
for (let i = 0; i < data.length; ++i) {
funnels.push(data[i][0], data[i][1][NetTrans.current_throughput][0] * 8, data[i][1][NetTrans.current_throughput][1] * 8);
//funnels.push(data[i][0], data[i][1][NetTrans.current_throughput][0] * 8, data[i][1][NetTrans.current_throughput][1] * 8);
funnels.ingest(data[i][0], data[i][1][NetTrans.current_throughput][0] * 8, data[i][1][NetTrans.current_throughput][1] * 8);
rtts[data[i][0]] = new RttHistogram();
let row = "<div class='row row220'>";
@ -660,33 +680,38 @@
}
$("#pills-funnel").html(html);
builtFunnelDivs = true;
setTimeout(plotFunnels, 10);
});
}
let plottedFunnels = {};
function plotFunnels() {
if (tpData != null) tpData.plot("tp_client");
funnels.prepare();
msgPackGet("/api/funnel_for_queue/" + encodeURI(circuitId), (data) => {
for (let i = 0; i < data.length; ++i) {
funnels.push(data[i][0], data[i][1][NetTrans.current_throughput][0] * 8, data[i][1][NetTrans.current_throughput][1] * 8);
for (const [k, v] of Object.entries(funnels.data)) {
rtts[data[i][0]].clear();
funnels.ingest(data[i][0], data[i][1][NetTrans.current_throughput][0] * 8, data[i][1][NetTrans.current_throughput][1] * 8);
for (let j = 0; j < data[i][1][NetTrans.rtts].length; j++) {
rtts[data[i][0]].push(data[i][1][NetTrans.rtts][j]);
}
rtts[data[i][0]].plot("rtt" + data[i][0]);
}
for (const [k, v] of Object.entries(funnels.y)) {
let target_div = "tp" + k;
let graphData = v.toScatterGraphData();
let graphData = [
{ x: funnels.x_axis, y: v, type: 'scatter', mode: 'markers', marker: { size: 3 } }
];
let graph = document.getElementById(target_div);
if (!plotFunnels.hasOwnProperty(target_div)) {
Plotly.newPlot(graph, graphData, { margin: { l: 0, r: 0, b: 0, t: 0, pad: 4 }, yaxis: { automargin: true }, xaxis: { automargin: true, title: "Time since now" } }, { responsive: true });
Plotly.newPlot(graph, graphData, { margin: { l: 0, r: 0, b: 0, t: 0, pad: 4 }, yaxis: { automargin: true, title: "Traffic (bits)" }, xaxis: { automargin: true, title: "Time since now" } });
} else {
Plotly.redraw(graph, graphData);
}
}
rtts[data[i][0]].clear();
for (let j = 0; j < data[i][1][NetTrans.rtts].length; j++) {
rtts[data[i][0]].push(data[i][1][NetTrans.rtts][j]);
}
rtts[data[i][0]].plot("rtt" + data[i][0]);
}
});
}
@ -846,6 +871,7 @@
switch (activeTab) {
case "pills-funnel-tab": {
getFunnel();
getThroughput();
} break;
case "pills-flows-tab": {
getFlows();