capsite/toybox: a mount outlives its handler: the vat restarts on demand
A handler is a live reference, held by the VatAdmin DO; workerd evicts an idle DO within seconds, and with it the handler, so a vat's page went 503 almost at once. createVat now keeps a vat's params when they hold only data and ingresses (an ingress by its key: the VatAdmin can make it again), and which vat was given which ingress. A request for a mount with no handler restarts that vat with its params; it rebuilds its root, serves again, and the request is answered. A vat whose params hold another peer's objects isn't restartable yet. The test crashes its own toybox (a crash ends every session to it), and the creator waits for the root's handoff before it disconnects, as scripts/hello.js now does too. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
a984461cee
commit
e5ed407e55
4 files changed
+160
-17
No files matched your search
@@ -12,11 +12,8 @@ const vatSrc = (name) => readFile(join(here, "vats", name), "utf8");
|
||||
|
||||
let dir, port, server, client;
|
||||
|
||||
before(async () => {
|
||||
dir = await mkdtemp(join(tmpdir(), "toybox-ocapn-"));
|
||||
await mkdir(join(dir, "state"));
|
||||
port = await freePort();
|
||||
server = await startWorkerd(
|
||||
const startToybox = () =>
|
||||
startWorkerd(
|
||||
"config.capnp",
|
||||
[
|
||||
"-s", `http=127.0.0.1:${port}`, "-s", `admin=unix:${join(dir, "admin.sock")}`,
|
||||
@@ -25,6 +22,12 @@ before(async () => {
|
||||
{ port, host: "127.0.0.1" },
|
||||
[join(dir, "admin.sock")],
|
||||
);
|
||||
|
||||
before(async () => {
|
||||
dir = await mkdtemp(join(tmpdir(), "toybox-ocapn-"));
|
||||
await mkdir(join(dir, "state"));
|
||||
port = await freePort();
|
||||
server = await startToybox();
|
||||
client = await connectClient(join(dir, "admin.sock"), "client-1", { verbose: !!process.env.OCAPN_LOG });
|
||||
});
|
||||
|
||||
@@ -66,3 +69,37 @@ test("an ingress nobody serves is a 503", async () => {
|
||||
await E(client.vatAdmin).makeIngress({ vat: "idle" });
|
||||
assert.equal((await fetch(`http://127.0.0.1:${port}/?vat=idle`)).status, 503);
|
||||
});
|
||||
|
||||
test("after a crash, a request restarts the vat that serves it", async () => {
|
||||
// its own toybox: a crash breaks every session to it, the shared client's too
|
||||
const home = await mkdtemp(join(tmpdir(), "toybox-phoenix-"));
|
||||
await mkdir(join(home, "state"));
|
||||
const port2 = await freePort();
|
||||
const start = () =>
|
||||
startWorkerd(
|
||||
"config.capnp",
|
||||
[
|
||||
"-s", `http=127.0.0.1:${port2}`, "-s", `admin=unix:${join(home, "admin.sock")}`,
|
||||
"-d", `state=${join(home, "state")}`, "-e", `switchboard=unix:${join(home, "no-switchboard.sock")}`,
|
||||
],
|
||||
{ port: port2, host: "127.0.0.1" },
|
||||
[join(home, "admin.sock")],
|
||||
);
|
||||
let toybox = await start();
|
||||
try {
|
||||
const creator = await connectClient(join(home, "admin.sock"), "creator");
|
||||
const ingress = await E(creator.vatAdmin).makeIngress({ vat: "phoenix" });
|
||||
const { root } = await E(creator.vatAdmin).createVat(await vatSrc("hello.js"), { ingress });
|
||||
assert.equal((await fetch(`http://127.0.0.1:${port2}/?vat=phoenix`)).status, 200);
|
||||
await root; // its handoff, settled before the client goes
|
||||
creator.close();
|
||||
await toybox.stop();
|
||||
toybox = await start();
|
||||
const resp = await fetch(`http://127.0.0.1:${port2}/again?vat=phoenix`);
|
||||
assert.equal(resp.status, 200);
|
||||
assert.match(await resp.text(), /Hello, world.*at \/again/);
|
||||
} finally {
|
||||
await toybox.stop();
|
||||
await rm(home, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
Reference in new issue
Block a user