wasi-common support for tokio, & wiggle support for async methods containing sync code#2832
wasi-common support for tokio, & wiggle support for async methods containing sync code#2832
Conversation
Subscribe to Label Actioncc @kubkon DetailsThis issue or pull request has been labeled: "wasi"Thus the following users have been cc'd because of the following labels:
To subscribe or unsubscribe from this label, edit the |
…ield are async methods
615a8f2 to
3d61c2a
Compare
Co-authored-by: Alex Crichton <alex@alexcrichton.com>
3d61c2a to
7590198
Compare
Subscribe to Label Actioncc @peterhuene DetailsThis issue or pull request has been labeled: "wasmtime:c-api"Thus the following users have been cc'd because of the following labels:
To subscribe or unsubscribe from this label, edit the |
only fn as_any(&self) -> &dyn Any doesnt get to be async.
and also a dummy C example
alexcrichton
left a comment
There was a problem hiding this comment.
👍 Nice!
I think there could be some more comments in a few places, and I've only somewhat lightly reviewed all the tokio scheduler bits but I think this looks pretty good. I keep finding it a bit backwards that all the sync stuff looks async but isn't, but it's all at least encapsulated.
alexcrichton
left a comment
There was a problem hiding this comment.
Ok all looks good to me! I think it's ok to leave the windows poll issue to, well, an issue for now. Other than that seems good to go for me! (although there's some CI failures)
permit both readable events to be delivered in very short interval, rather than simultaneously.
This PR makes it possible for
wasi-commonto work on with async executor liketokio, without taking a dependency on any sort of asynchronous runtime. Existing users ofwasi-commonwill not need to make any changes.It introduces the new crate
wasi-tokio, which is a sibling crate towasi-cap-std-sync, and also depending onwasi-cap-std-sync, since much of the implementation has been reused.wasmtime-wigglenow supports running async methods via a dummy executor, in order to support running synchronous wasi-common implementations. To configure this mode inwasmtime-wiggle, use the newblock_onconfiguration option in place ofasyncas introduced in #2701. This mode executes the async methods in a "dummy executor" - a mockedstd::task::Wakerwhich will only poll a future correctly if it immediately returnsPoll::Ready.wasi-commonnow uses anasync_traitto make eachWasiFile,WasiDir, andWasiSchedtrait methodasync. This means that any operation on files, directories, or the scheduler may return a pending future depending on the impl of those traits.wasi-cap-std-syncstays the same, modulo the code golf required to addasyncin front of some fns. All of these impls are synchronous - the futures returned by these will always bePoll::Ready. Therefore, it is safe to use with the dummy executor.The
WasiFiletrait has two additional methods,async fn readable(&mut self) -> Result<(), Error>and a correspondingwritable, which have semantics corresponding to a wasiSubscription::FdReadandFdWrite- the futures are ready when the file is ready to read or write. These methods are intended to be used by an impl ofWasiSched::poll_oneoff.wasi-tokiois implemented mostly in terms ofwasi-cap-std-sync. cap-std provides a robust implementation of filesystem sandboxing, which we still need to rely on. All file and directory operations delegated to thewasi-cap-std-syncimpl are wrapped intokio::task::block_in_place, which tells the tokio runtime to execute that code on a thread that may block. This is how tokio's ownFiletype treats all of its IO operations as well. The departure ofwasi-tokiofrom wasi-cap-std-sync is in the impl of theWasiFile::{readable, writable}methods, which usetokio::io::unix::AsyncFdwhen available, and theWasiSched::poll_oneoffmethod is implemented using those futures andtokio::time::timeout.Unfortunately, tokio's AsyncFd doesn't do very much in this context on Linux (
epoll(2)doesn't operate on regular files), and isn't available at all on Windows, but at least on Mac OS it does work well withkqueue(2). So, on Linux we are basically stuck making believe that regular files are immediately readable and writable, which is as much asselectdoes for us anyway. The futures do work properly on pipes like stdin. On Windows, tokio doesn't give us anything like AsyncFd, so we fall back on using the cap-std-sync windows poll_oneoff inside a block_in_place.wasmtime-wasinow exports two differentWasis - one undersync::when thesyncfeature is enabled (which it is by default), and one undertokio::when thetokiofeature is enabled (not a default). The sync implementation is re-exported at the root of the crate, so that existing users do not have to change their code.A new top-level
examples/tokioshows usingwasmtime_wasi::tokio::Wasiundertokio. It incorporates a lot of comments @alexcrichton wrote previously.