Builtin Library
README.md
world_vcs.derive.runner
Turns staged assets into reservations and computes them on job-system workers. world.add and world.add_all call reserveAndStart once staging settles.
reserveAndStart(stageName, stagedPaths)plans the derive hooks that accept the assets holding the staged paths and reserves every planned output on the stage in one call before it returns, with a pending (empty) fingerprint. It then reads each reservation'sgeneration, and after it the staged inputs, so it computes from that version of the inputs or a newer one; it fingerprints the assets on workers (every dispatch made before the first answer is awaited) and computes each output on a worker. Each output is written beside its asset, unless its reservation was reserved again meanwhile, and its reservation settleddone, which stages the output into the reservation's stage in the same backend call; the settle carries the fingerprint of the inputs it was computed from, which a pending reservation records and a reservation that states another fingerprint refuses, and the generation it read: a settle at any other generation is refused (the inputs were staged again, and the computation of the newer ones answers for the output), and a settle at the current generation of a reservation alreadydonechanges nothing, so two engines computing the same version is harmless. A hook that raises, or runs past itstimeout, settlesfailedwith the reason and names no output.- A snapshot covers the whole asset: the files of the tree its stage's commit lands on, with the staged entries laid over them, and never the output the hook itself computes. That tree is the branch head with the caller's commits sealed before the stage laid over it, oldest first: a commit lands after the ones sealed before it and is rebased onto the head it finds.
- Staging an asset again with the inputs the stage already holds for it (
snapshot.stagedInputs: each staged file's address and the assets its reference table pins, a referenced folder asset whose files the stage holds by those files, so an output landing in it changes nothing) reserves nothing when this engine reserved its output for those inputs on that stage and is computing it or has settled itdone: the reservation and its computation stay as they are. A staging that changes the inputs reserves the output again, and the run of the earlier keying is cancelled. - A run is cancelled when its output is reserved again or dropped. A cancelled run computes nothing it has not started: an engine-thread hook (
engineCompute) is handed the run as its third argument, and one still waiting to start (a preview waiting for the stage it renders on) ends there. Nothing a cancelled run produces is written or settled. - The engine-thread work runs in units (preparing each asset, checking the reservation's generation, writing the output, settling it), each started only while the frame's shared slice (
modules.frame_budget) has room, so a batch of any size runs across frames at the engine's frame rate. resume(stageName?)dispatches again everycomputingreservation of the stage and of the caller's sealed stages that this engine is not computing, whichever engine or session reserved it. Each stage is read by its row id, entries and reservations together, and a reservation computes from the entries of its own stage laid over the tree that stage lands on, so a sealed commit's output is computed from what the commit holds. A reservation whose hook no engine has registered stayscomputing.status()answers{ computing, preparing, failed, statusReads };failedcounts the failed settles the backend recorded,statusReadsthe whole-status reads the runner made (a reservation's generation is a read of its own row).- An output is written to its live path only when the snapshot it was computed from holds the live asset's files; a computation from other inputs (a sealed stage's, an older stage's) stores its bytes in the blob store by content address, settles
doneat that address, and leaves the live file alone. - A staged hook output (a
preview.pngswept in byzm add .) plans no reservation: only a change of the asset's inputs does. Neither does a staged file an install places where the world holds no row of its own: an installed asset is reserved only when the stage changes a file of it that is the world's own. - The snapshot of an asset that holds files of the world's own also holds the files an install places beside them (
snapshot.placedFiles), read from the working tree: the commit carries them through the install's record, so an installed asset the world edited is computed whole. A file an install placed at the output's path is no live output of the world's: the computed bytes are written there, which makes the world's own file at that path, and a write that leaves the install's file in place settlesemptywhen the bytes are the same andfailedotherwise. - A settle refused because its reservation is gone drops the computation and tells no one: the staging area released the reservation once it no longer staged a change of the asset (the change was unstaged, the area emptied), or committed or closed.
- A settle the backend refuses settles
failedwith the refusal as its reason, so the commit waiting on it is told why and a resume does not compute it again. A refusal for a fingerprint the reservation states for other inputs drops this computation, and a reservation whose failure is refused too posts a notice namingzm derived retry; a resume of this engine leaves either one alone until it is reserved again. A settle that raises before the backend answers leaves the reservation computing for a resume to compute again, three times in all; then this engine leaves it alone until it is reserved again and posts a notice namingzm derived retry,zm derived provideandzm unseal. - An asset that holds no input file of the world's own in the tree its commit lands on nor in the working tree has nothing to derive: the commit removes it, or every input file it holds is one an install places at a path the world holds no row of, which the install's record carries together with the outputs its publisher computed (an update of an install an earlier engine landed as one row per file leaves its assets so). Its reservation settles
empty, so the commit waits on no output of it and lands none.resume,retryandcarrysettle such a reservation the same way, anddropof a required output of such an asset settles itempty. An asset whose working tree holds input files of the world's own that the commit does not settlesfailed, naming thezm addthat stages them (afterzm unsealfor a sealed commit, sincezm addstages into the staging area).
A result is cached by hook name and fingerprint (derive.cache), so staging the same inputs again writes the cached bytes without computing.
local runner = require("modules.world_vcs.derive.runner")
runner.reserveAndStart("default", { "/zero/source/gold.material/mat.yaml" })
print(runner.status().computing)