The fix a commit ago buffered messages only while QUEUED, which is the window a page creates for ITS OWN run. Reattach opens a second window nobody covered: the socket is live, the phase is idle, and the queue has not yet said which run belongs here. Anything arriving in that gap fell straight through and was dropped -- and a run that ended inside it had already left `queue_running` by the time it was asked about, so nothing found it either. The GPU produced a picture, the app said Ready, and the result was gone. Held whenever the id is unknown, not only while queueing. Then two questions on load rather than one: what is still running, and -- if nothing is -- which of the runs this page actually SAW on its own socket was ours, answered from ComfyUI's history by the client id it recorded. Only ids seen during this page load are asked about, so a result from an hour ago cannot be resurrected as though it had just arrived. Every reattach test called adopt() before sending anything, so none of them was ever in the window that adopt() exists to close.
92 lines
3.2 KiB
JavaScript
92 lines
3.2 KiB
JavaScript
// Reattaching to a run that outlived the page.
|
|
|
|
import test from "node:test";
|
|
import assert from "node:assert/strict";
|
|
|
|
import { runningFor, finishedFor } from "../client.js";
|
|
|
|
const answering = (body, ok = true) => async () => ({
|
|
ok, status: ok ? 200 : 500, json: async () => body,
|
|
});
|
|
|
|
test("the run this browser queued is found by its client id", async () => {
|
|
const promptId = await runningFor("me", {
|
|
fetch: answering({
|
|
queue_running: [
|
|
[1, "someone-elses", {}, { client_id: "them" }, []],
|
|
[2, "mine", {}, { client_id: "me" }, []],
|
|
],
|
|
}),
|
|
});
|
|
assert.equal(promptId, "mine");
|
|
});
|
|
|
|
test("another browser's run is not adopted", async () => {
|
|
const promptId = await runningFor("me", {
|
|
fetch: answering({ queue_running: [[1, "theirs", {}, { client_id: "them" }, []]] }),
|
|
});
|
|
assert.equal(promptId, null);
|
|
});
|
|
|
|
test("nothing running means nothing to reattach to", async () => {
|
|
assert.equal(await runningFor("me", { fetch: answering({ queue_running: [] }) }), null);
|
|
});
|
|
|
|
test("a queue that cannot be reached is not an error the app has to show", async () => {
|
|
// The dev server has no queue behind it, which is the ordinary case while
|
|
// working on the UI.
|
|
const promptId = await runningFor("me", {
|
|
fetch: async () => { throw new TypeError("Failed to fetch"); },
|
|
});
|
|
assert.equal(promptId, null);
|
|
});
|
|
|
|
test("a malformed queue entry is skipped rather than crashing the load", async () => {
|
|
const promptId = await runningFor("me", {
|
|
fetch: answering({ queue_running: [null, "nonsense", [1], [2, "mine", {}, { client_id: "me" }, []]] }),
|
|
});
|
|
assert.equal(promptId, "mine");
|
|
});
|
|
|
|
test("a finished run is recognised as this browser's from its history entry", async () => {
|
|
const asked = [];
|
|
const promptId = await finishedFor("me", ["theirs", "mine"], {
|
|
fetch: async (url) => {
|
|
asked.push(url);
|
|
const id = url.split("/").pop();
|
|
const owner = id === "mine" ? "me" : "them";
|
|
return { ok: true, status: 200, json: async () => ({
|
|
[id]: { prompt: [1, id, {}, { client_id: owner }, []], outputs: {}, status: {} },
|
|
}) };
|
|
},
|
|
});
|
|
assert.equal(promptId, "mine");
|
|
// Newest first: the run that just ended is the one being looked for.
|
|
assert.equal(asked[0], "/history/mine");
|
|
});
|
|
|
|
test("a finished run belonging to someone else is not adopted", async () => {
|
|
const promptId = await finishedFor("me", ["theirs"], {
|
|
fetch: async (url) => ({ ok: true, status: 200, json: async () => ({
|
|
theirs: { prompt: [1, "theirs", {}, { client_id: "them" }, []] },
|
|
}) }),
|
|
});
|
|
assert.equal(promptId, null);
|
|
});
|
|
|
|
test("a history entry with nothing in it is skipped, not trusted", async () => {
|
|
for (const body of [{}, { mine: {} }, { mine: { prompt: [] } }, { mine: { prompt: [1, "mine", {}] } }]) {
|
|
const promptId = await finishedFor("me", ["mine"], {
|
|
fetch: async () => ({ ok: true, status: 200, json: async () => body }),
|
|
});
|
|
assert.equal(promptId, null, JSON.stringify(body));
|
|
}
|
|
});
|
|
|
|
test("no history to ask is not an error", async () => {
|
|
const promptId = await finishedFor("me", ["mine"], {
|
|
fetch: async () => { throw new TypeError("Failed to fetch"); },
|
|
});
|
|
assert.equal(promptId, null);
|
|
});
|