Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Epochs don't interrupt binaries with long time.Sleep durations #233

Open
cedric-cordenier opened this issue Sep 17, 2024 · 3 comments
Open

Comments

@cedric-cordenier
Copy link

Hi!

I'm trying to execute the following go snippet compiled to WASM:

package main

import time

func main() {
    time.Sleep(10 * time.Second)
}

and am using an epoch deadline (set to "3"), which is being incremented every 100 milliseconds. In other words, the deadline for this is 300 milliseconds.

However, this isn't behaving as I expect using wasmtime-go: with the wasm trap only firing after the time.Sleep call has completed.

Is this expected behaviour?

Thanks!

@alexcrichton
Copy link
Member

This is sort of expected behavior, sort of not. It's expected in that, yes, with wasmtime-go that's expected. This is a caveat of epochs where epochs are used to cancel executing wasm code but don't assist in cancelling host code. For cancelling host code that's left up to the embedder. The primary way of doing that is to use the async support that Wasmtime has, for example bytecodealliance/wasmtime#9184 and bytecodealliance/wasmtime#9188 are similar issues to the one here but for the wasmtime CLI (which switched over to using async).

So the "not expected" part is that Wasmtime does natively have support to fix this, but that comes back to the "this is expected" part in that the async parts of Wasmtime aren't exposed in Go at this time. There's a C API but it's not bound in Go yet.

@cedric-cordenier
Copy link
Author

cedric-cordenier commented Sep 17, 2024

Hey @alexcrichton, thanks! Do you see a workaround to this issue? For imports that I can control, I think the workaround is straight-forward, we just need to ensure that we are respecting some timeout. However, AFAIU time.Sleep reduces to a call to the wasi syscall poll_oneoff which is not something I have control of. I can stub it out, but that raises the question generally of how we enforce timeouts on the wasi imports defined by wasmtime-go.

And just for my understanding: are you anticipating that support for these async parts of wasmtime will be released soon for wasmtime-go?

BTW if it's helpful I'd be happy to take a look at binding the relevant C API to Go if you can point me in the right direction?

@alexcrichton
Copy link
Member

Yeah unfortunately there's not a great solution at this time because as you're seeing the imports in question are the ones provided by Wasmtime. You could theoretically define your own implementation of WASI and skip adding Wasmtime's own implementation, but even then you'd still have to orchestrate timeouts and such yourself (e.g. wake up the host function that's blocked on sleeping once the timeout elapses).

Currently there's no one working on adding support for the async APIs to Go, so that's an open project which if you'd like you can pick up. Exactly how it would integrate within Go I'm not sure myself, though, so it'll probably require a chunk of design work to figure out how to best fit within Go's idioms.

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

No branches or pull requests

2 participants