Skip to content

feat(vm): persistent worker reuse and synchronous proxy gas cost - #224

Open
jaspersagent wants to merge 2 commits into
sedaprotocol:mainfrom
jaspersagent:feat/vm-persistent-worker
Open

feat(vm): persistent worker reuse and synchronous proxy gas cost#224
jaspersagent wants to merge 2 commits into
sedaprotocol:mainfrom
jaspersagent:feat/vm-persistent-worker

Conversation

@jaspersagent

@jaspersagent jaspersagent commented Jun 10, 2026

Copy link
Copy Markdown

Disclaimer: All numbers mentioned are just my local machine, I'm sure we'll get significantly better / different numbers on our production machines.

Makes the existing Atomics worker mode usable as a persistent single-execution engine. Previously callVm assumed a one-shot worker: listeners were never removed, messages carried no call identity, and a passed-in worker was terminated on completion, so consumers wanting to avoid the in-process abort-and-replay cost (3 wasm executions per proxy_http_fetch) had to pay a worker spawn per call instead. Reusing one worker per thread brings a measured 102ms to 17ms p50 per data request in the seda-candles executer under production-shaped load. All message traffic is now scoped by a nonce-suffixed process id, listeners detach on settle, the worker keeps a thread-local WasmModuleCache (the host's instance does not survive structured clone), Atomics waits carry a configurable hostCallTimeoutMs so a dead host cannot wedge the worker forever, and crash-synthesized results are flagged so pool implementations can fail over. A second commit adds an optional getProxyHttpFetchGasCostSync adapter hook so flat-fee adapters skip one abort-and-replay execution in the in-process mode; both changes are additive and the in-process replay path is byte-for-byte unchanged for adapters that opt out.

  • The reuse contract is one in-flight call per worker (the notifier buffer is per-call state); queueing stays with the caller.
  • Version bumped to 1.2.0. seda-candles currently rides these changes as a bun patch on 1.1.3 (sedaprotocol/seda-candles#108) and will switch to ^1.2.0 once released.

A passed-in Worker can now be reused across sequential callVm calls:
all message traffic is scoped by a per-call process id (nonce-suffixed
so identical call data never collides), listeners detach when a call
settles, and only internally spawned workers are terminated. The worker
keeps a local WasmModuleCache since the host's instance does not
survive structured clone, host-call Atomics waits carry a configurable
timeout so a dead host cannot wedge the worker thread forever, and
results synthesized from worker error/exit are flagged with crashed so
pools can distinguish a dead worker from a non-zero program exit.
Adapters with a flat fee model can implement the optional
getProxyHttpFetchGasCostSync to resolve the proxy gas cost without a
host action. In the in-process mode every host action aborts and
replays the wasm from the start, so answering synchronously removes one
full execution per proxy fetch. Returning undefined falls back to the
async host action, and worker (Atomics) mode is unaffected since host
actions never abort there.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant