in src/ComputerDisplay.js [57:247]
render() {
function classify_node(n) {
const node = n.displayName;
if (/^c5.xlarge-i-.*$/.test(node)) {
return "linux-cpu";
}
if (/^c5.4xlarge-i-.*$/.test(node)) {
return "linux-bigcpu";
}
if (/^g3.8xlarge-i-.*$/.test(node)) {
if (n.assignedLabels.some((l) => l.name === "tc_gpu")) {
return "linux-tc-gpu";
} else {
return "linux-gpu";
}
}
if (/^g3.16xlarge-i-.*$/.test(node)) {
return "linux-multigpu";
}
if (/^worker-c5-xlarge-.*$/.test(node)) {
return "linux-cpu-ccache";
}
if (/^worker-macos-high-sierra-.*$/.test(node)) {
return "osx";
}
if (/^worker-win-c5.2xlarge-i-.*$/.test(node)) {
return "win-cpu";
}
if (/^worker-win-g3.4xlarge-i-.*$/.test(node)) {
return "win-gpu";
}
if (/^worker-osuosl-ppc64le-cpu-.*$/.test(node)) {
return "ppc";
}
if (/^worker-packet-type-1-.*$/.test(node)) {
return "packet";
}
if (/^jenkins-worker-rocm-.*$/.test(node)) {
return "rocm";
}
if (/^worker-g3-4xlarge-.*$/.test(node)) {
return "tc-gpu";
}
return node;
}
const map = new Map();
this.state.computer.forEach((c) => {
const k = classify_node(c);
let v = map.get(k);
if (v === undefined) v = { busy: 0, total: 0 };
if (!c.offline) {
v.total++;
if (!c.idle) v.busy++;
}
map.set(k, v);
});
let totalCost = 0;
map.forEach((v, k) => {
const perCost = centsPerHour[k];
if (perCost !== undefined) {
v.totalCost = perCost * v.total;
totalCost += v.totalCost;
}
});
const rows = [...map.entries()].sort().map((kv) => {
const cost = centsToDollars(kv[1].totalCost);
return (
<tr key={kv[0]}>
<th>{kv[0]}</th>
<td>
{kv[1].busy} / {kv[1].total}
</td>
<td className="ralign">{cost}/hr</td>
</tr>
);
});
const busy_nodes = this.state.computer.filter(
(c) =>
!c.idle &&
c.displayName !== "master" &&
c.executors.length > 0 &&
c.executors[0].currentExecutable
);
busy_nodes.sort(
(a, b) =>
a.executors[0].currentExecutable.timestamp -
b.executors[0].currentExecutable.timestamp
);
const running_rows = busy_nodes.map((c) => {
const executable = c.executors[0].currentExecutable;
return (
<tr key={c.displayName}>
<td className="left-cell">{summarize_ago(executable.timestamp)}</td>
<td>
<a href={executable.url}>{summarize_url(executable.url)}</a>
</td>
</tr>
);
});
const running_map = new Map();
busy_nodes.forEach((c) => {
const executable = c.executors[0].currentExecutable;
const task = summarize_url(executable.url);
let v = running_map.get(task);
if (v === undefined) {
v = { total: 0, cumulative_time: 0 };
running_map.set(task, v);
}
v.total++;
function delta_ago(timestamp) {
const date = new Date(timestamp);
const today = new Date();
return (today - date) / 1000;
}
v.cumulative_time += delta_ago(executable.timestamp);
});
/*
const running_summary = [...running_map.entries()].sort((a, b) => b[1].total - a[1].total).map(task_v => {
const task = task_v[0];
const v = task_v[1];
return <tr key={task}><td style={{textAlign: "right", paddingRight: 15}}>{v.total}</td><th>{task}</th></tr>
});
const cumulative_running_time_summary = [...running_map.entries()].sort((a, b) => b[1].cumulative_time - a[1].cumulative_time).map(task_v => {
const task = task_v[0];
const v = task_v[1];
return <tr key={task}><td style={{textAlign: "right", paddingRight: 15}}>{seconds2time(Math.floor(v.cumulative_time))}</td><th>{task}</th></tr>
});
*/
return (
<div>
<h2>
Computers{" "}
<AsOf
interval={this.props.interval}
currentTime={this.state.currentTime}
updateTime={this.state.updateTime}
connectedIn={this.state.connectedIn}
/>
</h2>
<table>
<tbody>
<tr>
<td>
<table>
<tbody>{rows}</tbody>
<tfoot>
<tr>
<td></td>
<td className="ralign" colSpan="2">
{centsToDollars(totalCost * 24 * 30)}/mo
</td>
</tr>
</tfoot>
</table>
</td>
<td className="right-cell">
<table>
<tbody>{running_rows}</tbody>
</table>
</td>
{/*
<td className="right-cell">
<table>
<tbody>
{running_summary}
</tbody>
</table>
</td>
<td className="right-cell">
<table>
<tbody>
{cumulative_running_time_summary}
</tbody>
</table>
</td>
*/}
</tr>
</tbody>
</table>
</div>
);
}