mirror of
https://github.com/badlogic/pi-mono.git
synced 2026-11-05 23:37:25 +00:00
chord/next/http: a Web fetch handler built from the registry Http (routes, wraps, sockets, hosts, relays, CSP sources) and Authenticators, responses as descriptions, a security baseline on by default, Chord's own Node listener as a host-lifetime object, nodeRequest for apps mounting it, links and plugin sockets. chord/next/workers: a forked worker per address, started on demand, stopped when idle, never restarted by itself, plugins built by the server and shipped. Plugins: kinds with platform and host packages, createPluginRuntime, scripts(kind), rollout results per host, imports of other plugins by name. Kernel: RouteHandle (retry, suspend), no route backoff, anonymous host.root, origins only from relays. ws is an optional peer dependency.
46 lines
1.8 KiB
TypeScript
46 lines
1.8 KiB
TypeScript
// Tests of worker processes (slice 10 §3): forked with their output piped (the stderr tail kept), the link made at the
|
|
// fork (an early frame queued), control messages told, and the whole tree killed.
|
|
|
|
import { fileURLToPath } from "node:url";
|
|
import { describe, expect, it } from "vitest";
|
|
import type { FromWorker } from "../../../src/next-node/workers/control.ts";
|
|
import { WorkerProcess } from "../../../src/next-node/workers/process.ts";
|
|
import { until } from "./support.ts";
|
|
|
|
const CHILD = fileURLToPath(new URL("../fixtures/workers/child.ts", import.meta.url));
|
|
|
|
/** Whether process `pid` lives. */
|
|
function alive(pid: number): boolean {
|
|
try {
|
|
process.kill(pid, 0);
|
|
return true;
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
describe("a worker process", () => {
|
|
it("pipes its output, keeps its stderr tail, queues an early frame on its link, tells control messages", async () => {
|
|
const output: string[] = [];
|
|
const control: FromWorker[] = [];
|
|
const child = new WorkerProcess(
|
|
{
|
|
entry: CHILD,
|
|
execArgv: ["--conditions=source", "--experimental-strip-types", "--no-warnings"],
|
|
onOutput: (stream, chunk) => output.push(`${stream}: ${Buffer.from(chunk).toString().trim()}`),
|
|
},
|
|
{ control: (message) => control.push(message), linkLost: () => {}, linkClosed: () => {}, exited: () => {} },
|
|
);
|
|
await until(() => control.length > 0 && output.length >= 2);
|
|
const frames: number[][] = [];
|
|
child.link.onMessage((message) => frames.push([...message]));
|
|
expect(frames).toEqual([[1, 2, 3]]);
|
|
expect(control).toEqual([{ kind: "started" }]);
|
|
expect(child.stderrTail).toBe("an error line\n");
|
|
const grandchild = Number(/grandchild (\d+)/.exec(output.join("\n"))![1]);
|
|
expect(alive(grandchild)).toBe(true);
|
|
child.kill();
|
|
expect(await child.exited).toEqual({ code: null, signal: "SIGKILL" });
|
|
await until(() => !alive(grandchild), 2_000);
|
|
});
|
|
});
|