fixing bugs
This commit is contained in:
parent
5433679785
commit
654221d956
|
|
@ -1,30 +1,84 @@
|
||||||
async function loadTargets() {
|
// cockpit/fester-module/targets.js
|
||||||
|
|
||||||
const res = await fetch("/api/targets");
|
/**
|
||||||
const data = await res.json();
|
* Fester Targets Module
|
||||||
|
* Handles nodes, edges, metrics, heatmaps, and live updates for cockpit UI.
|
||||||
|
*/
|
||||||
|
|
||||||
const sys = document.getElementById("system");
|
(function(global) {
|
||||||
const arch = document.getElementById("arch");
|
|
||||||
const runtime = document.getElementById("runtime");
|
|
||||||
|
|
||||||
data.systems.forEach(s => {
|
const targetsModule = {
|
||||||
let o = document.createElement("option");
|
nodes: {},
|
||||||
o.value = s;
|
edges: [],
|
||||||
o.text = s;
|
metrics: {},
|
||||||
sys.appendChild(o);
|
heatmaps: {},
|
||||||
});
|
callbacks: [],
|
||||||
|
|
||||||
data.arches.forEach(a => {
|
/**
|
||||||
let o = document.createElement("option");
|
* Register a callback to receive updated DAG data
|
||||||
o.value = a;
|
*/
|
||||||
o.text = a;
|
onUpdate(callback) {
|
||||||
arch.appendChild(o);
|
if (typeof callback === 'function') {
|
||||||
});
|
this.callbacks.push(callback);
|
||||||
|
|
||||||
data.runtimes.forEach(r => {
|
|
||||||
let o = document.createElement("option");
|
|
||||||
o.value = r;
|
|
||||||
o.text = r;
|
|
||||||
runtime.appendChild(o);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the internal state from WS or iframe message
|
||||||
|
*/
|
||||||
|
update(data) {
|
||||||
|
if (!data) return;
|
||||||
|
|
||||||
|
if (data.nodes) {
|
||||||
|
data.nodes.forEach(node => this.nodes[node.id] = node);
|
||||||
|
}
|
||||||
|
if (data.edges) {
|
||||||
|
this.edges = data.edges;
|
||||||
|
}
|
||||||
|
if (data.metrics) {
|
||||||
|
Object.assign(this.metrics, data.metrics);
|
||||||
|
}
|
||||||
|
if (data.heatmaps) {
|
||||||
|
Object.assign(this.heatmaps, data.heatmaps);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.dispatch();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify all registered callbacks with the updated data
|
||||||
|
*/
|
||||||
|
dispatch() {
|
||||||
|
const snapshot = {
|
||||||
|
nodes: Object.values(this.nodes),
|
||||||
|
edges: this.edges,
|
||||||
|
metrics: this.metrics,
|
||||||
|
heatmaps: this.heatmaps
|
||||||
|
};
|
||||||
|
this.callbacks.forEach(cb => cb(snapshot));
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear all stored DAG state
|
||||||
|
*/
|
||||||
|
clear() {
|
||||||
|
this.nodes = {};
|
||||||
|
this.edges = [];
|
||||||
|
this.metrics = {};
|
||||||
|
this.heatmaps = {};
|
||||||
|
this.dispatch();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Listen for iframe messages from cockpit.html
|
||||||
|
window.addEventListener('message', (event) => {
|
||||||
|
const data = event.data;
|
||||||
|
if (data && typeof data === 'object') {
|
||||||
|
targetsModule.update(data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Expose module globally
|
||||||
|
global.FesterTargets = targetsModule;
|
||||||
|
|
||||||
|
})(window);
|
||||||
|
|
|
||||||
|
|
@ -2,242 +2,56 @@
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Fester Debug Cockpit</title>
|
<title>Fester Cockpit</title>
|
||||||
|
<link rel="stylesheet" href="../../style.css">
|
||||||
<style>
|
<style>
|
||||||
body {
|
body { margin: 0; font-family: Arial, sans-serif; background: #1e1e1e; color: #eee; }
|
||||||
margin: 0;
|
header { background: #2c2c2c; padding: 10px; font-size: 1.2em; display: flex; align-items: center; }
|
||||||
font-family: sans-serif;
|
header h1 { flex: 1; margin: 0; font-weight: normal; }
|
||||||
background: #0b0f14;
|
#tabs { display: flex; background: #252525; }
|
||||||
color: #d0d0d0;
|
.tab { flex: 1; text-align: center; padding: 10px; cursor: pointer; }
|
||||||
}
|
.tab.active { background: #3a3a3a; }
|
||||||
|
iframe { border: none; width: 100%; height: calc(100vh - 80px); }
|
||||||
#layout {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 320px 1fr 320px;
|
|
||||||
height: 100vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------
|
|
||||||
CONTROL PANEL
|
|
||||||
------------------------- */
|
|
||||||
#controls {
|
|
||||||
padding: 12px;
|
|
||||||
border-right: 1px solid #1f2a38;
|
|
||||||
background: #0e141d;
|
|
||||||
}
|
|
||||||
|
|
||||||
select, button {
|
|
||||||
width: 100%;
|
|
||||||
margin: 6px 0;
|
|
||||||
padding: 6px;
|
|
||||||
background: #1a2432;
|
|
||||||
color: #ddd;
|
|
||||||
border: 1px solid #2c3b4d;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------
|
|
||||||
GRAPH
|
|
||||||
------------------------- */
|
|
||||||
#graph {
|
|
||||||
position: relative;
|
|
||||||
overflow: auto;
|
|
||||||
background: #05070b;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------
|
|
||||||
DEBUG PANEL
|
|
||||||
------------------------- */
|
|
||||||
#debug {
|
|
||||||
padding: 12px;
|
|
||||||
border-left: 1px solid #1f2a38;
|
|
||||||
background: #0e141d;
|
|
||||||
font-size: 12px;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.node {
|
|
||||||
position: absolute;
|
|
||||||
width: 130px;
|
|
||||||
padding: 8px;
|
|
||||||
border-radius: 6px;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 11px;
|
|
||||||
background: #1b2430;
|
|
||||||
border: 1px solid #333;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* states */
|
|
||||||
.node.running { border-color: #ffb300; }
|
|
||||||
.node.done { border-color: #66bb6a; }
|
|
||||||
.node.failed { border-color: #ef5350; }
|
|
||||||
.node.scheduled { border-color: #42a5f5; }
|
|
||||||
|
|
||||||
.highlight {
|
|
||||||
outline: 2px solid #ffd54f;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div id="layout">
|
<header>
|
||||||
|
<h1>Fester Cockpit</h1>
|
||||||
<!-- LEFT -->
|
</header>
|
||||||
<div id="controls">
|
|
||||||
|
|
||||||
<h3>Build Control</h3>
|
|
||||||
|
|
||||||
<select id="arch">
|
|
||||||
<option>x86_64</option>
|
|
||||||
<option>arm64</option>
|
|
||||||
<option>riscv64</option>
|
|
||||||
</select>
|
|
||||||
|
|
||||||
<select id="target">
|
|
||||||
<option>linux-glibc</option>
|
|
||||||
<option>linux-musl</option>
|
|
||||||
<option>openwrt</option>
|
|
||||||
</select>
|
|
||||||
|
|
||||||
<select id="toolchain">
|
|
||||||
<option>gcc</option>
|
|
||||||
<option>clang</option>
|
|
||||||
</select>
|
|
||||||
|
|
||||||
<button onclick="startBuild()">Start Build</button>
|
|
||||||
|
|
||||||
|
<div id="tabs">
|
||||||
|
<div class="tab active" data-target="live_dag">Live DAG</div>
|
||||||
|
<div class="tab" data-target="replay">Replay / Debugger</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- CENTER -->
|
<iframe id="cockpit-frame" src="../../ui/live_dag.html"></iframe>
|
||||||
<div id="graph"></div>
|
|
||||||
|
|
||||||
<!-- RIGHT DEBUG -->
|
|
||||||
<div id="debug">
|
|
||||||
<h3>Node Debugger</h3>
|
|
||||||
<div id="trace">Select a node</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
<script src="./targets.js"></script>
|
||||||
<script>
|
<script>
|
||||||
|
// Tab switching logic
|
||||||
const ws = new WebSocket("ws://localhost:8080/ws");
|
const tabs = document.querySelectorAll('.tab');
|
||||||
|
const iframe = document.getElementById('cockpit-frame');
|
||||||
const nodes = {};
|
tabs.forEach(tab => {
|
||||||
const traces = {};
|
tab.addEventListener('click', () => {
|
||||||
const deps = {};
|
tabs.forEach(t => t.classList.remove('active'));
|
||||||
|
tab.classList.add('active');
|
||||||
// -------------------------
|
iframe.src = tab.dataset.target === 'live_dag' ? '../../ui/live_dag.html' : '../../ui/replay.html';
|
||||||
// POSITIONING
|
});
|
||||||
// -------------------------
|
|
||||||
let index = 0;
|
|
||||||
|
|
||||||
function pos(name) {
|
|
||||||
if (nodes[name]) return nodes[name].pos;
|
|
||||||
|
|
||||||
const p = {
|
|
||||||
x: 80 + (index % 4) * 200,
|
|
||||||
y: 80 + Math.floor(index / 4) * 120
|
|
||||||
};
|
|
||||||
|
|
||||||
index++;
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------
|
|
||||||
// NODE CLICK DEBUGGER
|
|
||||||
// -------------------------
|
|
||||||
function showTrace(name) {
|
|
||||||
|
|
||||||
const trace = traces[name];
|
|
||||||
|
|
||||||
const panel = document.getElementById("trace");
|
|
||||||
|
|
||||||
if (!trace) {
|
|
||||||
panel.innerHTML = "No trace data yet";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
panel.innerHTML = `
|
|
||||||
<b>${name}</b><br><br>
|
|
||||||
|
|
||||||
<b>State:</b> ${trace.state}<br>
|
|
||||||
<b>Cache:</b> ${trace.cache || "unknown"}<br>
|
|
||||||
<b>Node:</b> ${trace.node || "n/a"}<br>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<b>Scheduler Score Breakdown</b><br>
|
|
||||||
CPU: ${trace.score?.cpu || 0}<br>
|
|
||||||
Thermal: ${trace.score?.thermal || 0}<br>
|
|
||||||
Stability: ${trace.score?.instability || 0}<br>
|
|
||||||
Final: ${trace.score?.final || 0}<br>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<b>Deps:</b><br>
|
|
||||||
${(trace.deps || []).join(", ")}
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------
|
|
||||||
// WEBSOCKET
|
|
||||||
// -------------------------
|
|
||||||
ws.onmessage = (msg) => {
|
|
||||||
|
|
||||||
const event = JSON.parse(msg.data);
|
|
||||||
|
|
||||||
if (event.type !== "node") return;
|
|
||||||
|
|
||||||
const n = event.data.node;
|
|
||||||
|
|
||||||
traces[n] = {
|
|
||||||
...traces[n],
|
|
||||||
...event.data
|
|
||||||
};
|
|
||||||
|
|
||||||
// create node
|
|
||||||
if (!nodes[n]) {
|
|
||||||
|
|
||||||
const el = document.createElement("div");
|
|
||||||
el.className = "node";
|
|
||||||
el.innerText = n;
|
|
||||||
|
|
||||||
const p = pos(n);
|
|
||||||
el.style.left = p.x + "px";
|
|
||||||
el.style.top = p.y + "px";
|
|
||||||
|
|
||||||
el.onclick = () => showTrace(n);
|
|
||||||
|
|
||||||
document.getElementById("graph").appendChild(el);
|
|
||||||
|
|
||||||
nodes[n] = { el, pos: p };
|
|
||||||
}
|
|
||||||
|
|
||||||
const el = nodes[n].el;
|
|
||||||
|
|
||||||
el.classList.remove("running","done","failed","scheduled");
|
|
||||||
el.classList.add(event.data.state);
|
|
||||||
};
|
|
||||||
|
|
||||||
// -------------------------
|
|
||||||
// START BUILD
|
|
||||||
// -------------------------
|
|
||||||
function startBuild() {
|
|
||||||
|
|
||||||
fetch("/api/build", {
|
|
||||||
method: "POST",
|
|
||||||
headers: {"Content-Type":"application/json"},
|
|
||||||
body: JSON.stringify({
|
|
||||||
arch: arch.value,
|
|
||||||
target: target.value,
|
|
||||||
toolchain: toolchain.value
|
|
||||||
})
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
|
// Initialize WebSocket connection and dispatch events to iframe
|
||||||
|
const ws = new WebSocket(`ws://${window.location.hostname}:8080/ws`);
|
||||||
|
ws.onopen = () => console.log("Cockpit WS connected");
|
||||||
|
ws.onmessage = (event) => {
|
||||||
|
try {
|
||||||
|
const data = JSON.parse(event.data);
|
||||||
|
// Forward event to iframe
|
||||||
|
iframe.contentWindow.postMessage(data, '*');
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Invalid WS event", err);
|
||||||
|
}
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
|
||||||
240
ui/live_dag.html
240
ui/live_dag.html
|
|
@ -1,169 +1,123 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<title>Fester Live DAG + Cause Graph</title>
|
<meta charset="UTF-8">
|
||||||
|
<title>Fester Live DAG</title>
|
||||||
|
<link rel="stylesheet" href="../style.css">
|
||||||
<style>
|
<style>
|
||||||
body {
|
body { font-family: sans-serif; margin: 0; overflow: hidden; }
|
||||||
font-family: monospace;
|
#graph { position: relative; width: 100vw; height: 100vh; background: #111; }
|
||||||
background: #0e0f12;
|
|
||||||
color: #d0d0d0;
|
|
||||||
margin: 0;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
#graph {
|
|
||||||
position: relative;
|
|
||||||
width: 100vw;
|
|
||||||
height: 100vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
.node {
|
.node {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
padding: 8px 10px;
|
width: 120px;
|
||||||
|
height: 40px;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 40px;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
font-size: 12px;
|
color: white;
|
||||||
min-width: 140px;
|
font-weight: bold;
|
||||||
transition: all 0.2s ease;
|
cursor: pointer;
|
||||||
border: 1px solid #333;
|
transition: background 0.3s, transform 0.2s;
|
||||||
}
|
}
|
||||||
|
svg.edge {
|
||||||
.edge {
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
height: 2px;
|
top: 0; left: 0;
|
||||||
background: #444;
|
width: 100%; height: 100%;
|
||||||
transform-origin: left center;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
.heatmap {
|
||||||
.tooltip {
|
border: 2px solid yellow;
|
||||||
position: absolute;
|
|
||||||
background: #111;
|
|
||||||
border: 1px solid #333;
|
|
||||||
padding: 6px;
|
|
||||||
font-size: 11px;
|
|
||||||
display: none;
|
|
||||||
max-width: 300px;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div id="graph"></div>
|
<div id="graph"></div>
|
||||||
<div id="tooltip" class="tooltip"></div>
|
<svg id="edges" class="edge"></svg>
|
||||||
|
|
||||||
|
<script src="../cockpit/fester-module/targets.js"></script>
|
||||||
<script>
|
<script>
|
||||||
|
const graphEl = document.getElementById('graph');
|
||||||
|
const edgesSVG = document.getElementById('edges');
|
||||||
|
|
||||||
|
function createNodeElement(node) {
|
||||||
|
const el = document.createElement('div');
|
||||||
|
el.className = 'node';
|
||||||
|
el.id = `node-${node.id}`;
|
||||||
|
el.style.left = `${node.x || Math.random() * (window.innerWidth-150)}px`;
|
||||||
|
el.style.top = `${node.y || Math.random() * (window.innerHeight-50)}px`;
|
||||||
|
el.innerText = node.name || node.id;
|
||||||
|
graphEl.appendChild(el);
|
||||||
|
return el;
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateNode(node) {
|
||||||
|
let el = document.getElementById(`node-${node.id}`);
|
||||||
|
if (!el) {
|
||||||
|
el = createNodeElement(node);
|
||||||
|
}
|
||||||
|
el.innerText = node.name || node.id;
|
||||||
|
|
||||||
|
// color based on state
|
||||||
|
switch(node.state) {
|
||||||
|
case 'done': el.style.background = 'green'; break;
|
||||||
|
case 'running': el.style.background = 'orange'; break;
|
||||||
|
case 'failed': el.style.background = 'red'; break;
|
||||||
|
default: el.style.background = 'gray';
|
||||||
|
}
|
||||||
|
|
||||||
|
// heatmap border
|
||||||
|
if (node.heatmap) {
|
||||||
|
el.classList.add('heatmap');
|
||||||
|
} else {
|
||||||
|
el.classList.remove('heatmap');
|
||||||
|
}
|
||||||
|
|
||||||
|
return el;
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawEdges(edges, nodes) {
|
||||||
|
edgesSVG.innerHTML = '';
|
||||||
|
edges.forEach(edge => {
|
||||||
|
const fromEl = document.getElementById(`node-${edge.from}`);
|
||||||
|
const toEl = document.getElementById(`node-${edge.to}`);
|
||||||
|
if (!fromEl || !toEl) return;
|
||||||
|
|
||||||
|
const line = document.createElementNS('http://www.w3.org/2000/svg','line');
|
||||||
|
const fromRect = fromEl.getBoundingClientRect();
|
||||||
|
const toRect = toEl.getBoundingClientRect();
|
||||||
|
line.setAttribute('x1', fromRect.left + fromRect.width/2);
|
||||||
|
line.setAttribute('y1', fromRect.top + fromRect.height/2);
|
||||||
|
line.setAttribute('x2', toRect.left + toRect.width/2);
|
||||||
|
line.setAttribute('y2', toRect.top + toRect.height/2);
|
||||||
|
line.setAttribute('stroke', 'white');
|
||||||
|
line.setAttribute('stroke-width', '2');
|
||||||
|
edgesSVG.appendChild(line);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// subscribe to FesterTargets updates
|
||||||
|
FesterTargets.onUpdate(snapshot => {
|
||||||
|
snapshot.nodes.forEach(updateNode);
|
||||||
|
drawEdges(snapshot.edges, snapshot.nodes);
|
||||||
|
});
|
||||||
|
|
||||||
|
// connect to WebSocket
|
||||||
const ws = new WebSocket("ws://localhost:8080/ws");
|
const ws = new WebSocket("ws://localhost:8080/ws");
|
||||||
|
ws.onmessage = msg => {
|
||||||
const nodes = {};
|
|
||||||
const edges = {};
|
|
||||||
const graph = document.getElementById("graph");
|
|
||||||
const tooltip = document.getElementById("tooltip");
|
|
||||||
|
|
||||||
function getColor(state) {
|
|
||||||
return {
|
|
||||||
"scheduled": "#2b6cb0",
|
|
||||||
"running": "#dd6b20",
|
|
||||||
"done": "#2f855a",
|
|
||||||
"failed": "#c53030",
|
|
||||||
"hit": "#805ad5"
|
|
||||||
}[state] || "#444";
|
|
||||||
}
|
|
||||||
|
|
||||||
function drawNode(id, label, state, x, y) {
|
|
||||||
|
|
||||||
if (!nodes[id]) {
|
|
||||||
const el = document.createElement("div");
|
|
||||||
el.className = "node";
|
|
||||||
graph.appendChild(el);
|
|
||||||
nodes[id] = el;
|
|
||||||
|
|
||||||
el.onmousemove = (e) => {
|
|
||||||
tooltip.style.display = "block";
|
|
||||||
tooltip.style.left = e.pageX + 10 + "px";
|
|
||||||
tooltip.style.top = e.pageY + 10 + "px";
|
|
||||||
};
|
|
||||||
|
|
||||||
el.onmouseleave = () => {
|
|
||||||
tooltip.style.display = "none";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const el = nodes[id];
|
|
||||||
|
|
||||||
el.innerText = `${label}\n${state}`;
|
|
||||||
el.style.background = getColor(state);
|
|
||||||
el.style.left = x + "px";
|
|
||||||
el.style.top = y + "px";
|
|
||||||
}
|
|
||||||
|
|
||||||
function drawEdge(id, x1, y1, x2, y2) {
|
|
||||||
|
|
||||||
if (!edges[id]) {
|
|
||||||
const el = document.createElement("div");
|
|
||||||
el.className = "edge";
|
|
||||||
graph.appendChild(el);
|
|
||||||
edges[id] = el;
|
|
||||||
}
|
|
||||||
|
|
||||||
const el = edges[id];
|
|
||||||
|
|
||||||
const dx = x2 - x1;
|
|
||||||
const dy = y2 - y1;
|
|
||||||
const length = Math.sqrt(dx*dx + dy*dy);
|
|
||||||
|
|
||||||
el.style.width = length + "px";
|
|
||||||
el.style.left = x1 + "px";
|
|
||||||
el.style.top = y1 + "px";
|
|
||||||
el.style.transform = `rotate(${Math.atan2(dy, dx)}rad)`;
|
|
||||||
}
|
|
||||||
|
|
||||||
ws.onmessage = (msg) => {
|
|
||||||
|
|
||||||
const event = JSON.parse(msg.data);
|
const event = JSON.parse(msg.data);
|
||||||
|
if (event.type === 'node') {
|
||||||
// ----------------------------
|
const n = event.data.node;
|
||||||
// NODE UPDATE
|
const state = event.data.state;
|
||||||
// ----------------------------
|
FesterTargets.update({ nodes: [{ id: n, name: n, state: state }] });
|
||||||
if (event.type === "task_update") {
|
|
||||||
|
|
||||||
const key = event.node + ":" + event.action;
|
|
||||||
|
|
||||||
const x = Math.random() * window.innerWidth * 0.8;
|
|
||||||
const y = Math.random() * window.innerHeight * 0.8;
|
|
||||||
|
|
||||||
drawNode(
|
|
||||||
key,
|
|
||||||
event.action,
|
|
||||||
event.state,
|
|
||||||
x,
|
|
||||||
y
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
if (event.type === 'pipeline') {
|
||||||
// ----------------------------
|
console.log('Pipeline event:', event.data);
|
||||||
// FAILURE HIGHLIGHT
|
|
||||||
// ----------------------------
|
|
||||||
if (event.type === "failure") {
|
|
||||||
|
|
||||||
const key = event.node + ":" + event.action;
|
|
||||||
|
|
||||||
if (nodes[key]) {
|
|
||||||
nodes[key].style.boxShadow = "0 0 12px red";
|
|
||||||
}
|
}
|
||||||
}
|
if (event.type === 'heatmap') {
|
||||||
|
// { id: 'node1', heatmap: true }
|
||||||
// ----------------------------
|
FesterTargets.update({ nodes: [event.data] });
|
||||||
// CAUSE GRAPH HOOK (NEW)
|
|
||||||
// ----------------------------
|
|
||||||
if (event.type === "debug") {
|
|
||||||
|
|
||||||
tooltip.innerText = JSON.stringify(event, null, 2);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue