Files
Jamie Pineandcapy-ai-staging[bot] b9385262f0 Load WASM extensions in the daemon and run their jobs with checkpoint and resume (#3122)
* Load WASM extensions in the daemon and run their jobs with checkpoint and resume

The plugin manager now keeps each extension's store and instance for its
lifetime, discovers every manifest under <data dir>/extensions at startup
before libraries open, and runs a registered job export on a blocking
thread. The job host functions report into the running WasmJob through a
bridge: progress, warnings, metrics, an interrupt flag the pause path
sets, and checkpoints that land in the checkpoint table before the guest
continues, so a pause or a kill resumes from the guest's last state.

extensions.list and extensions.run_job expose the registry on the wire.
The SDK's #[job] export calls the job function (async ones through a poll
loop) and plugin_init installs a panic hook so a guest panic reaches the
host log. wasmer moves to 6.1 because 4.4 no longer links on Rust 1.89+
(wasmer #5610). The test extension calls check_interrupt_sync, the name
the SDK has for the synchronous check, and drops uuid's v4 feature it
never used so it builds for wasm32-unknown-unknown again.

The integration suite loads the committed fixture, runs the counter to
completion, and pauses, restarts and resumes it; the whole integration
group builds with the wasm feature so the suite shares one sd-core build.

Co-authored-by: capy-ai-staging[bot] <305915985+capy-ai-staging[bot]@users.noreply.github.com>

* Build and load the photos extension and stop at the first missing host function

The photos extension builds for wasm32-unknown-unknown without
wasm-bindgen imports: uuid and chrono drop their JS features, entropy is
the unsupported getrandom backend until the SDK has a host function for
it, and the FaceDetection glob ambiguity is resolved. Its four jobs get
registered names and are listed in the extension macro, so plugin_init
registers them. The committed photos.wasm fixture loads beside the test
extension in the integration suite; its first job fails at
JobContext::run, which has no host function, with the panic in the host
log.

Co-authored-by: capy-ai-staging[bot] <305915985+capy-ai-staging[bot]@users.noreply.github.com>

* Keep guest progress messages, reload a trapped plugin, reload by directory

Progress from a guest carried a message the host read and dropped; it now
reaches the job as generic progress with the job name as its phase. A
trap poisons the plugin runtime and the next job reloads the extension
from disk, since an aborted guest may have died holding its allocator.
reload_plugin reads the directory the plugin came from instead of
assuming it equals the manifest id.

Co-authored-by: capy-ai-staging[bot] <305915985+capy-ai-staging[bot]@users.noreply.github.com>

* Probe a trapped plugin without its mutex and swap in the reload only on success

The poison flag lives in an atomic beside the runtime, so the next job
reads it under the manager's read lock instead of waiting on the mutex a
running job holds, and the write lock is taken only for the reload. A
reload reads, compiles and instantiates the new instance before the old
one is unloaded, so a failed reload leaves the plugin as it was. A job
that reached a poisoned instance fails instead of running on it.

Co-authored-by: capy-ai-staging[bot] <305915985+capy-ai-staging[bot]@users.noreply.github.com>

* Put the old plugin back when a reload's plugin_init fails; read mutex poison too

A reload whose fresh instance fails plugin_init re-registers the old
plugin's jobs and reinserts it, so one bad reload is one error rather
than a missing extension. The poison probe also reads a poisoned runtime
mutex, which a panic unwinding out of a guest call leaves behind without
reaching the flag.

Co-authored-by: capy-ai-staging[bot] <305915985+capy-ai-staging[bot]@users.noreply.github.com>

* Run the WASM extension suite in the acceptance group with its own build

wasmer in sd-core adds minutes to every test binary link, so carrying the
wasm feature across the integration group took it from 51 to 78 minutes.
The suite now builds alone with the feature in the acceptance job, which
had 16 minutes to spare.

Co-authored-by: capy-ai-staging[bot] <305915985+capy-ai-staging[bot]@users.noreply.github.com>

---------

Co-authored-by: capy-ai-staging[bot] <305915985+capy-ai-staging[bot]@users.noreply.github.com>
2026-10-07 17:45:56 +00:00
..
…