Browser runners: a tab runs WASM jobs issue #80 open andymccall opened this · 1 comment
andymccall set labels feature ·
andymccall edited ·
andymccall referenced by change 39e737fbc7a9 on main ·
First part built (hub, goes out with 0.9.15): Run in this tab, /OWNER/NAME/flow/tab, linked from Flow. It lists the pipeline's WASM jobs on a bookmark; a Web Worker (/static/wasi-worker.js) fetches the bookmark's zip once, unpacks it in memory (central directory, stored and deflate-raw via DecompressionStream), and runs each job's modules with an in-memory WASI preview 1 shim: /src and . preopened, the job's args and env (PWD=/src), stdout/stderr streamed by line, files writable in memory, unknown imports answer ENOSYS, * module patterns resolved as flow does. Checked in Node against oxygenflow's .flow/checks.wasm: layout, todos, size and summary give flow's output and exit codes. Nothing is claimed or reported yet.
What is left, in order:
- Register a tab as a runner. A signed-in member presses Offer this tab; the page makes an Ed25519 key in WebCrypto (non-extractable) and the hub registers a runner for the member's own repositories with label
browser, tierwasmonly, trust classdevice(anonymouswould need issue #79 first). The browser cannot build an oxyIdentityobject itself, so the hub makes it from the raw public key and a name, and signs nothing on the tab's behalf. - Claim and run. The worker polls
/api/v1/flow/claimwithruntimes: ["wasm"], fetches the job's state as a zip by its state hash (a newarchive?state=the claim's token may read, scoped to the job'sscope), runs it, sends log batches and finishes with exit code, duration and peak memory. - Receipts. The receipt's canonical encoding is Rust (
flow_core::receipt); rather than port it, the hub hands the tab the bytes to sign (the receipt it would expect, canonical), the tab signs them with its WebCrypto key, and the hub checks the signature against the registered key as for any runner. - Drain.
visibilitychangeto hidden andpagehideleave (issue #76): hand the job back; a tab never holds a lease past being hidden. - Limits. A memory limit by checking the module's memory after each growth is not possible from JS; cap it by refusing modules whose declared maximum exceeds the sandbox's
memory-limit, and say so.
A page on the hub turns the tab into a WASM-tier runner (issue #75) in a Web Worker: WASI through a shim, OPFS for files, outputs uploaded as for any runner, the key kept non-extractable in WebCrypto; trust class
anonymousunless signed in as a member (device). Closing or hiding the tab drains it (issue #76). Mostly the demonstration that handover and spot checks hold for the least reliable runner of all. Design: docs/handover.md §10.