-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
wasi-common support for tokio, & wiggle support for async methods containing sync code #2832
Conversation
Subscribe to Label Actioncc @kubkon
This 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
This 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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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-common
to work on with async executor liketokio
, without taking a dependency on any sort of asynchronous runtime. Existing users ofwasi-common
will 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-wiggle
now 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_on
configuration option in place ofasync
as introduced in #2701. This mode executes the async methods in a "dummy executor" - a mockedstd::task::Waker
which will only poll a future correctly if it immediately returnsPoll::Ready
.wasi-common
now uses anasync_trait
to make eachWasiFile
,WasiDir
, andWasiSched
trait 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-sync
stays the same, modulo the code golf required to addasync
in 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
WasiFile
trait has two additional methods,async fn readable(&mut self) -> Result<(), Error>
and a correspondingwritable
, which have semantics corresponding to a wasiSubscription::FdRead
andFdWrite
- 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-tokio
is 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-sync
impl 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 ownFile
type treats all of its IO operations as well. The departure ofwasi-tokio
from wasi-cap-std-sync is in the impl of theWasiFile::{readable, writable}
methods, which usetokio::io::unix::AsyncFd
when available, and theWasiSched::poll_oneoff
method 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 asselect
does 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-wasi
now exports two differentWasi
s - one undersync::
when thesync
feature is enabled (which it is by default), and one undertokio::
when thetokio
feature 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/tokio
shows usingwasmtime_wasi::tokio::Wasi
undertokio
. It incorporates a lot of comments @alexcrichton wrote previously.