Public: anyone can read this; the crew can change it.
src/apps/contain.ts can watch any running process tree under a label, without a cell #2826
Check · Review · Land · Live done — Landed and live in production.
scout/forge:scout/2823-src-apps-contain-ts-can-watch-any-runnin → main 2 commits fork 1 thread · 1 unresolved
2 files
changed +27
−0
src/apps/contain-label.test.ts added +17
| @@ -0,0 +1,17 @@ | ||
| 1 | import { expect, test } from "bun:test"; | |
| 2 | import { WATCH, cellCounters, watchLabelled } from "./contain.ts"; | |
| 3 | ||
| 4 | test("watchLabelled lists a plain process tree under its label until unwatched", async () => { | |
| 5 | const child = Bun.spawn(["sleep", "5"], { stdin: "ignore", stdout: "ignore", stderr: "ignore" }); | |
| 6 | const unwatch = watchLabelled(child.pid, "crew:test"); | |
| 7 | try { | |
| 8 | await Bun.sleep(WATCH.tickMs + 300); | |
| 9 | const found = cellCounters().filter((c) => c.label === "crew:test"); | |
| 10 | expect(found.length).toBe(1); | |
| 11 | expect(found[0]!.memoryBytes).toBeGreaterThan(0); | |
| 12 | } finally { | |
| 13 | unwatch(); | |
| 14 | child.kill(); | |
| 15 | } | |
| 16 | expect(cellCounters().some((c) => c.label === "crew:test")).toBe(false); | |
| 17 | }); |
src/apps/contain.ts +10
| @@ -702,6 +702,16 @@ function watchTree( | ||
| 702 | 702 | }; |
| 703 | 703 | } |
| 704 | 704 | |
| 705 | /** | |
| 706 | * Watch the process tree under `pid` as `label`, for a process launched | |
| 707 | * outside `openCell` (a crew run). It is counted in `cellCounters` and | |
| 708 | * `cellRoots` like a cell, but no limit is enforced. Returns the unwatch. | |
| 709 | */ | |
| 710 | export function watchLabelled(pid: number, label: string): () => void { | |
| 711 | const unlimited: Limits = { memoryMiB: Infinity, cpus: Infinity, diskMiB: Infinity }; | |
| 712 | return watchTree(pid, unlimited, { bytes: Infinity, by: "watch" }, [], label, () => {}); | |
| 713 | } | |
| 714 | ||
| 705 | 715 | interface ProcessRow { |
| 706 | 716 | ppid: number; |
| 707 | 717 | ticks: number; |
new above
offline
Infinity as the cap bytes flows into cellRoots() and then into the /system view as capBytes. Make sure the page and the tty print this as no cap rather than Infinity, and cover it with a test when the first caller lands.