bytecodealliance / wasmtime

A fast and secure runtime for WebAssembly
https://wasmtime.dev/
Apache License 2.0
15.12k stars 1.27k forks source link

Add ability to stop running `wasmtime::Instance` #860

Closed rylev closed 4 years ago

rylev commented 4 years ago

Once a wasmtime::Instance in created the start function will be run. This may lead to the current thread being blocked for a long time. It would be helpful to have the ability to stop or pause an wasmtime::Instance while it is running.

alexcrichton commented 4 years ago

I'd be curious to hear other's thoughts on this as well, but two "lightweight" ways to do this could be:

Out of curiosity, you say "stop or pause" but I suspect "stop" is going to be a whole lot easier than "pause". Does your use case require the pausing aspect of resuming again later if something was stopped?

eminence commented 4 years ago

Related to #712

thomastaylor312 commented 4 years ago

I think both would be helpful. There is a use case for pausing a module as well, but for this specific issue, just being able to stop it is the main feature request

alexcrichton commented 4 years ago

Some other notes:


In https://github.com/bytecodealliance/wasmtime/issues/43 @sunfishcode says:

cranelift-wasm's FuncEnviron has a translate_loop_header callback which allows embedders to insert custom timeout code at the tops of loops (in addition to the tops of potentially recursive functions). Wasmtime doesn't yet implement timeouts, but this hook is one way it could do so.


In https://github.com/bytecodealliance/wasmtime/issues/712 @pchickey says:

Over in Lucet, @iximeow was able to find an implementation https://github.com/bytecodealliance/lucet/pull/150 that makes it possible to terminate running Wasm code due to either timeout or other external triggers, but it is pretty specific to the way stack switching to Wasm code works in Lucet.

We'd like to port Lucet's stack management code into Wasmtime as part of merging the Lucet project in, so I'd expect the kill switch mechanism to be ported in as well.

thomastaylor312 commented 4 years ago

@alexcrichton that sounds similar to the path we were starting to go down. so I'll follow along with those issues as well

moonheart08 commented 4 years ago

I personally probably have one of the sillier use-cases for the ability to pause/resume (I wanted to put WASM computers in Minecraft as an exercise), but it gives a few very important use cases for Wasmtime some light: 1) The traditional browser use-case of having separate isolated Wasmtime VMs up and going at once 2) The embedded into another application use-case in, say, a game, where the VM hanging the place would be disastrous, and you're under a strict schedule to get each frame out on time (and as such need a watchdog system, where each VM gets a per-frame budget of how much it gets to execute before pausing)

fitzgen commented 4 years ago

Note that pausing is harder than stopping because you have to save the execution state (stack and all that) so that you can pick it back up again later. We want this eventually since wasm will eventually get stack switching, but we can probably support interrupting and stopping long-running wasm modules sooner.

In addition to the translate loop header stuff, what we would need is a timer thread or something that sets a flag once a module has taken too long, and then the loop header (and function prologues!) would check that flag and do a custom interrupt trap if it is set.

zeroexcuses commented 10 months ago

Sorry, is there a way to pause + resume wasmtime instances right now?

Context: imagine an ant colony simulation, where each ant = tiny wasm vm; we want to run every ant for a bit, then pause it, let other ants run, etc ...

alexcrichton commented 10 months ago

Yes to do that you'd want to use Wasmtime's support for async. Fuel and epochs are the mechanisms to suspend computations. I'd also recommend opening a new issue and/or a thread on Zulip instead of posting on older issues.