Skip to content

Commit 751c517

Browse files
authored
cancel viz request after the kernel clicked away [pr] (tinygrad#9144)
1 parent 465421b commit 751c517

File tree

2 files changed

+26
-14
lines changed

2 files changed

+26
-14
lines changed

tinygrad/viz/index.html

+13-4
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@
307307
var currentKernel = -1;
308308
var currentRewrite = 0;
309309
var expandKernel = true;
310+
const evtSources = [];
310311
async function main() {
311312
const mainContainer = document.querySelector('.main-container');
312313
// ***** LHS kernels list
@@ -357,13 +358,23 @@
357358
});
358359
// ***** UOp graph
359360
if (currentKernel == -1) return;
360-
const cacheKey = `${currentKernel}-${currentUOp}`;
361+
const kernel = kernels[currentKernel][1][currentUOp];
362+
const cacheKey = `kernel=${currentKernel}&idx=${currentUOp}`;
363+
// close any pending event sources
364+
let activeSrc = null;
365+
for (const e of evtSources) {
366+
if (e.url.split("?")[1] !== cacheKey) e.close();
367+
else if (e.readyState === EventSource.OPEN) activeSrc = e;
368+
}
361369
if (cacheKey in cache) {
362370
ret = cache[cacheKey];
363371
}
364-
else {
372+
// if we don't have a complete cache yet we start streaming this kernel
373+
if (!(cacheKey in cache) || (cache[cacheKey].length !== kernel.match_count+1 && activeSrc == null)) {
365374
ret = [];
375+
cache[cacheKey] = ret;
366376
const eventSource = new EventSource(`/kernels?kernel=${currentKernel}&idx=${currentUOp}`);
377+
evtSources.push(eventSource);
367378
eventSource.onmessage = (e) => {
368379
if (e.data === "END") return eventSource.close();
369380
const chunk = JSON.parse(e.data);
@@ -374,14 +385,12 @@
374385
const gUl = document.getElementById(`rewrite-${ret.length-1}`);
375386
if (gUl != null) gUl.classList.remove("disabled");
376387
};
377-
cache[cacheKey] = ret;
378388
}
379389
if (ret.length === 0) return;
380390
renderGraph(ret[currentRewrite].graph, ret[currentRewrite].changed_nodes || []);
381391
// ***** RHS metadata
382392
const metadata = document.querySelector(".container.metadata");
383393
metadata.innerHTML = "";
384-
const kernel = kernels[currentKernel][1][currentUOp];
385394
metadata.appendChild(vsCodeOpener(kernel.loc.join(":").split("/")));
386395
metadata.appendChild(highlightedCodeBlock(kernel.code_line, "python", true));
387396
// ** code blocks

tinygrad/viz/serve.py

+13-10
Original file line numberDiff line numberDiff line change
@@ -132,16 +132,19 @@ def do_GET(self):
132132
if "kernel" in (query:=parse_qs(url.query)):
133133
def getarg(k:str,default=0): return int(query[k][0]) if k in query else default
134134
kidx, ridx = getarg("kernel"), getarg("idx")
135-
# stream details
136-
self.send_response(200)
137-
self.send_header("Content-Type", "text/event-stream")
138-
self.send_header("Cache-Control", "no-cache")
139-
self.end_headers()
140-
for r in get_details(contexts[0][kidx], contexts[1][kidx][ridx]):
141-
self.wfile.write(f"data: {json.dumps(r)}\n\n".encode("utf-8"))
142-
self.wfile.flush()
143-
self.wfile.write("data: END\n\n".encode("utf-8"))
144-
return self.wfile.flush()
135+
try:
136+
# stream details
137+
self.send_response(200)
138+
self.send_header("Content-Type", "text/event-stream")
139+
self.send_header("Cache-Control", "no-cache")
140+
self.end_headers()
141+
for r in get_details(contexts[0][kidx], contexts[1][kidx][ridx]):
142+
self.wfile.write(f"data: {json.dumps(r)}\n\n".encode("utf-8"))
143+
self.wfile.flush()
144+
self.wfile.write("data: END\n\n".encode("utf-8"))
145+
return self.wfile.flush()
146+
# pass if client closed connection
147+
except (BrokenPipeError, ConnectionResetError): return
145148
ret, content_type = json.dumps(kernels).encode(), "application/json"
146149
elif url.path == "/get_profile" and perfetto_profile is not None: ret, content_type = perfetto_profile, "application/json"
147150
else: status_code = 404

0 commit comments

Comments
 (0)