Repository navigation
Self update: releases side by side, and the daemon updates itself - #12
Open
IsuraManchanayake wants to merge 11 commits into
Open
IsuraManchanayake wants to merge 11 commits into
IsuraManchanayake wants to merge 11 commits into
Conversation
baseRT 0.3.1 defines BASERT_ABI_VERSION and exports baseRT_abi_version(): two libraries with the same number drive the same way, whatever their version numbers say. The build reads the macro from the vendored header (now 0.3.1's), the loader resolves the symbol when the library has it, and the numbers decide: equal serves, unequal is refused by number. A library that states none (0.3.0 and older), or a superfluid built against a header without the macro, is judged by major.minor as before. The symbol and configuration-struct checks stay. Library carries the number it found.
…s; superfluid compat; exit 4 A probe may state the contract number it checked the runtime against (Probe.abi: baseRT's engine ABI), the worker's check report carries it, and `superfluid runtimes --json` shows it as `abi` on a ready runtime. The basert row also carries `requires`, the header version and ABI number this build was built for, whether or not an engine was found, so a host can compare numbers itself. `superfluid compat [--json]` prints the same for a release. `superfluid serve` exits 4 when the runtime for the model is not installed or cannot run here (its engine library missing or of another ABI), where a flag it got wrong exits 2, so a host can tell the two apart. The catalog finds superfluid-workerd and the shipped adapters beside the real executable, links resolved: a superfluid reached through a symlink (a package manager's bin/, a host's shim) kept running the engine in-process because the link's directory held neither.
…at.json The page names the contract a host builds on: how to start superfluid (the real path, --runtime, --basert-lib and BASERT_KERNEL_LIB, --offline, one --sessions per server, SUPERFLUID_HOME), how to ask for the compatibility verdict before serving, how to choose a release from the compat.json each release now carries beside its tarball, and the exit codes. The CLI reference, the runtimes page and the changelog follow.
…he unnumbered line; the engine install chooses by ABI number The vendored header is baseRT 0.4.0's, so the fallback for a library that states no ABI number can no longer be "the header's minor": that would refuse 0.3.0, which carries ABI 1's functions and layouts without stating it. The line that does so is named instead, 0.3.x for ABI 1, and a library without a number serves only if it is of that line. No later ABI has such libraries. A library of 0.4.0 or later is asked for the model configuration by size (baseRT_get_config_into), into a zeroed struct of these bindings' own size, so the struct may grow or shrink between them without a change of ABI number; an older library is read by value with the size check as before. Every read of the configuration goes through config_of(). `superfluid runtime install basert` chooses by the same rule the loader applies: a release's ABI number, read from the basert-engine-abi-<N>.txt asset baseRT publishes beside its bundles, or a pin's, with the 0.3.x line accepted without one; another engine installs only with --untested. `superfluid compat` and the runtimes report name the unnumbered line too.
The pack step wrote dist/<name>.compat.json, but the artifact the release job downloads carried only the tarball and its digest, so the sidecar the docs promise beside the tarball never reached the release.
…s itself Releases live under $SUPERFLUID_HOME/versions/<v> with a `current` link that the commands on PATH go through. `superfluid self update` picks the newest release that fits the engine here, downloads and checks it, proves the copy starts, flips the link, keeps the version it replaced for `self use` and removes older ones; a running server is never written to. `serve` reads the listing once a day after it is up and prints one line when a newer release is out. The install script now places a release the same way, through `self install`, and a copy it placed before is migrated by its first update. The release carries the engine ABI number in an asset name, and compat.json is attached as documented.
… is made under the lock, the in-place copy is kept, and the check goes on Six findings of the review: - A version installed here is kept as it is; a copy of the same version placed again is used only when the one here no longer works, and only after the new copy is proved where it is, with the old set aside until the new one is in place. - The install script never writes through a link into versions/: a release from before self install is placed by the installed superfluid when one can, else copied with any link removed first. - An update takes the lock before reading current, on_disk or deciding forward-only, so an update queued behind another acts on what that one left; self use takes the same lock. - The first update of an in-place install keeps that copy under versions/ as the version it is, records it as previous, and leaves its workers while a server still runs from it. - The daily check goes on while the server runs: once an hour the cache is looked at again and the listing read when a day has passed.
… running from the install script's copy keeps its workerd Two findings of the re-review. A replacement that fails mid-copy leaves nothing of itself at the version's place and brings the copy set aside back, reporting both failures if that fails too. While a server runs from the copy the install script placed, only the superfluid command moves: its superfluid-workerd, superfluid-noded and workers stay, a migrating note is kept, and the next update, switch or install finishes the move once nothing runs from there. The install script's own path over an earlier copy keeps that copy as the version to go back to, as an update does, and follows the same rule.
clippy's zombie_processes lint on the running-server test: the spawned copy of the test binary is killed and waited for by a guard, whichever way the test ends.
This was referenced Oct 15, 2026
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #10: its diff includes #10 until that merges; this PR's own commits are the last five. I will rebase it onto
rc-0.1.3once #10 lands.What changed
Releases live under
$SUPERFLUID_HOME/versions/<v>/with acurrentlink that thesuperfluid,superfluid-workerdandsuperfluid-nodedcommands onPATHgo through; each version finds its workers beside its own executable, so a running server keeps its own workers after an update.self updatereads the release listing, takes the newest release for the platform that declares the engine's ABI here (by an asset namedsuperfluid-basert-abi-<N>.txt, elsecompat.json; with llama.cpp or MLX only, the newest), downloads the tarball and its.sha256into a staging directory, checks and unpacks, runs the copy's own--versionandruntimes --json, flipscurrentwith one rename, keeps the replaced version forself use, and prunes the rest, never a version with akeepfile or one a running process started from. Without--versionit only moves forward. One update, install or switch runs at a time. An installed version is never written to. A copy placed by the old install script is kept underversions/by its first update; Homebrew, cargo and source builds are refused with the right command named.After the server is up,
superfluid servereads the listing at most once a day, every hour while it stays up, and prints one line when a release newer than the running one fits here, held off three days after publication;--offlineorSUPERFLUID_NO_UPDATE_CHECK=1turns it off, andSUPERFLUID_RELEASESpoints at another listing.The install script now ends in
self install, placing a release the same way; the release workflow attaches the ABI marker asset and thecompat.jsonsidecar. New page: docs/serving/updating.md.Why
Today re-running the install script is the only update, it overwrites in place with no way back, and it swaps the workers under a running server. A host that installs superfluid for its engine needs to place a specific release beside whatever is there and run that version. The notify-only choice follows gh, Deno and Ollama's server: the daemon never downloads on its own.
How it was tested
cargo clippy --all-targets -- -D warnings, and-p superfluid --no-default-features: clean.cargo test -p superfluid selfupdate::: 13 tests against fake releases on disk with the listing passed in: the listing and the fit rule, where an executable came from, update, flip, prune, keep and use, the probe's refusals, immutability of an installed version and a replacement proved first, a switch waiting for a held lock, the migration keeping the old copy and a running legacy server's workerd, and the check announcing once and asking again when due.self installfrom the built tree,self list,self checkandself update --dry-runagainst the real GitHub listing (forward-only: 0.1.2 is older than this build), an update from a local 0.2.0 release with download, probe, flip, links and the previous kept,self useback and--versionforward without a download, the notice inside a realserveon the 0.3.0 engine, and the refusal for a source build.self installyet to hand off to), and the release workflow.Reviewed in the fork as IsuraManchanayake#8.
cargo clippy --all-targets -- -D warningscargo test