Stream: wasi

Topic: isyswasfa


view this post on Zulip Joel Dice (Jan 31 2024 at 05:30):

I made a prototype/polyfill for composable, Preview 3-style async: https://github.com/dicej/isyswasfa
It's still very experimental (I just got composition working this afternoon), but it's rapidly approaching usability.

I sync, you sync, we all sync for async! Contribute to dicej/isyswasfa development by creating an account on GitHub.

view this post on Zulip Ralph (Jan 31 2024 at 10:03):

That is absolutely great!

view this post on Zulip Ramon Klass (Jan 31 2024 at 11:57):

that name is great :)

view this post on Zulip Dave Bakker (badeend) (Jan 31 2024 at 13:24):

Interesting. How does it handle child components that call out to pollable::block or poll::poll? Would that be game-over for concurrency in the parent?

view this post on Zulip Joel Dice (Jan 31 2024 at 14:21):

Dave Bakker (badeend) said:

Interesting. How does it handle child components that call out to pollable::block or poll::poll? Would that be game-over for concurrency in the parent?

Correct -- none of the components in a composition should do blocking calls, just like with e.g. async functions in Rust. In practice, they can probably write to stdout (which technically involves a call to blocking_write_and_flush) since it won't block "much", but in general blocking hostcalls will block everything.

However, we do have a plan for composing async components with sync components (or more specifically, allowing async calls to synchronous, blocking, non-reentrant components). There's no way to do this with e.g. wasm-compose since the component model has no way to express this (yet!), but we can do it in the host at runtime. That's what this item in the "Planned features" section of README.md is about:

Host-side code generation for bridging async and sync components using backpressure to serialize async->sync calls without blocking the caller

The idea is to allow the host to mediate access to a sync component, providing backpressure to any and all async components which have made calls into that sync component.

view this post on Zulip Joel Dice (Jan 31 2024 at 14:43):

To clarify: this would be non-blocking backpressure -- i.e. the async component(s) would still be able to make progress on other things while awaiting the synchronous call. They can even make more calls to the same synchronous component concurrently, with the host serializing the calls automatically. The key to making that work would be to run each synchronous component in its own fiber, independent of the fiber running the async component(s).

view this post on Zulip Joel Dice (Jan 31 2024 at 14:45):

I expect @Luke Wagner will have more to say about that during the async session at the contributor summit.

view this post on Zulip Dave Bakker (badeend) (Jan 31 2024 at 14:58):

Alright. Got it.
Great work, BTw

view this post on Zulip Ralph (Jan 31 2024 at 15:18):

@Joel Dice can you elaborate on this a tad: Host-side code generation for bridging async and sync components using backpressure to serialize async->sync calls without blocking the caller from the readme?

view this post on Zulip Ralph (Jan 31 2024 at 15:18):

no hurry, of course, just wanna be sure I know what you're saying about this.

view this post on Zulip Joel Dice (Jan 31 2024 at 15:23):

@Ralph please see my response to Dave above and let me know if it needs more clarification

view this post on Zulip Ralph (Jan 31 2024 at 15:25):

I'm looking forward to Luke speaking today, of course. THIS was the phrase I meant: since the component model has no way to express this (yet!). I'm assuming you mean the async work we'll need in the expressions the model supports....?

view this post on Zulip Ralph (Jan 31 2024 at 15:25):

but in any case, I'll keep this in mind as luke's chat comes.....

view this post on Zulip Dave Bakker (badeend) (Jan 31 2024 at 15:31):

but we can do it in the host at runtime

I think this is referring to wasmtime's trampoline async_support, where "blocking" client calls are exposed as async to the host.

view this post on Zulip Joel Dice (Jan 31 2024 at 15:32):

I think the main discussion about async, led by Luke, is tomorrow if I'm reading the agenda correctly.

The goal with isyswasfa is to do as much as possible with guest- and host-side code generation to compensate for the lack of async support in the component model as it exists today. In the future, such hackery will not be necessary, and any component-model-capable host or composition tool will understand what it means to do an asynchronous call to a synchronous, non-reentrant component. For the time being, we need to build that on top of Wasmtime and it's fiber support, creating a fiber per synchronous component and communicating between them using e.g. async channels.

view this post on Zulip Joel Dice (Mar 12 2024 at 21:18):

A few quick updates on isyswasfa:

Next, I'll be shifting my focus to making isyswasfa obsolete as quickly as possible by implementing proper CM async support in wasm-tools, wasmtime, etc, working with Luke to nail down the design details as necessary.

I sync, you sync, we all sync for async! Contribute to dicej/isyswasfa development by creating an account on GitHub.

view this post on Zulip Ralph (Mar 12 2024 at 21:18):

yeoperson work here, @Joel Dice

view this post on Zulip Jeff Parsons (Mar 13 2024 at 21:28):

This is all unbelievably cool. :grinning:

Joel Dice said:

Next, I'll be shifting my focus to making isyswasfa obsolete as quickly as possible by implementing proper CM async support in wasm-tools, wasmtime, etc, working with Luke to nail down the design details as necessary.

I've been kinda half paying attention. Would you mind clarifying: is the general idea that this would theoretically be able to eventually be compatible with / make use of the core Wasm stack switching work, but for now not be blocked on any particular design emerging as the winner on that side of things?

view this post on Zulip Joel Dice (Mar 13 2024 at 21:37):

My opinion is that the MVP for composable async should not require or make use of stack switching, hence the focus on stackless coroutines (which should cover Rust, Python, JS, C#, etc. but not e.g. Go or Java). Eventually, we'll obviously want to support stackful coroutines as well, but I don't think that needs to be part of an MVP.

@Luke Wagner has pointed out that we don't necessarily need to wait for core stack switching to provide stackful coroutines -- we just need language toolchains to support reentrancy (i.e. allow the host to create multiple stacks for a single instance and use those stacks to support multiple concurrent calls). Core stack switching would presumably allow guests to also create multiple stacks, but we don't necessarily need that here.

view this post on Zulip Joel Dice (Mar 13 2024 at 21:41):

In a nutshell: I think we can do a lot with what toolchains produce today (i.e. non-reentrant modules), so we should go ahead and do that, and when toolchains start supporting reentrancy we'll be able to do even more.

view this post on Zulip Tarek Sander (Mar 14 2024 at 07:32):

Next, I'll be shifting my focus to making isyswasfa obsolete as quickly as possible by implementing proper CM async support in wasm-tools, wasmtime, etc, working with Luke to nail down the design details as necessary.

That's awesome! When do you expect there will be an experimental stream type to try? I'd like that for a proposed API, and since preview 2 is already released, preview 3 would be the earliest possible point of inclusion anyways.

view this post on Zulip IFcoltransG (Mar 14 2024 at 08:53):

Tarek Sander said:

I'd like that for a proposed API, and since preview 2 is already released, preview 3 would be the earliest possible point of inclusion anyways.

As I understand it, there will be some backwards compatible 0.2.* versions with additional APIs before 0.3. Breaking changes would go in 0.3. That means there might be opportunities for new APIs before stream types are released.

view this post on Zulip Joel Dice (Mar 14 2024 at 13:33):

Tarek Sander said:

That's awesome! When do you expect there will be an experimental stream type to try? I'd like that for a proposed API, and since preview 2 is already released, preview 3 would be the earliest possible point of inclusion anyways.

You can use stream<u8> in isywasfa today -- I had to implement (a polyfill of) it to support wasi:http@0.3.0-draft. The isyswasfa implementation is basically just syntactic sugar for wasi:io/streams@0.2.0#input-stream, plus a polyfill for the planned stream.new canon builtin which returns writable and readable handles as output-stream and input-stream instances, respectively. I.e. it's morally equivalent to what we're planning for real streams, modulo the use of isyswasfa in the names of things. If desired, we could generalize that to support stream<T> for arbitrary T using the same approach I used to implement future<T> for arbitrary T: synthesize a resource type for each unique T as needed.

But perhaps your question is not so much "when can I try this?", but rather "when can I use the real version, not the polyfill?". If so, the answer is: as soon as I've implemented it in wasm-tools, wasmtime, wit-bindgen, which I'm planning to do over the next few months.

And yes, per @IFcoltransG's comment: I suppose we could theoretically start using stream<T>, future<T>, and APIs which are meant to be lifted/lowered async in WASI 0.2.x releases, as long as it's done in a backwards compatible way. I'm not sure what the implications are of using new CM features in a WASI 0.2.x release, though; at a minimum we'd need to educate users that such a release has extra host implementation requirements that did not exist when WASI 0.2.0 was released.

view this post on Zulip Tarek Sander (Mar 14 2024 at 13:40):

Yes, stream<T> is what it'd like to use. Would awaiting work for multiple streams at once, or only one?

view this post on Zulip Joel Dice (Mar 14 2024 at 13:48):

Awaiting multiple streams concurrently would work just fine.

view this post on Zulip Simon (Mar 19 2024 at 14:55):

After trying out this out over the weekend, I'm also looking forward to a stream<T>

view this post on Zulip Randy Reddig (Mar 24 2024 at 08:32):

Mainline Go already uses multiple stacks per goroutine, separate from the wasm call stack. It should already be reentrant.

view this post on Zulip Joel Dice (Mar 24 2024 at 12:12):

Cool - that's great news. Does it also support Cgo, and if so, how does the C side of things manage multiple shadow stacks (i.e. the places where stack-allocated objects whose addresses have been taken reside)?

view this post on Zulip Randy Reddig (Mar 24 2024 at 19:14):

It doesn’t interact with Cgo at all.

view this post on Zulip Randy Reddig (Mar 24 2024 at 19:15):

Note: you might need a specific fork of TinyGo to use the output of this at the moment. We hope to land Component Model and WASI Preview 2 support in TinyGo soon.

view this post on Zulip Afshan Ahmed Khan (May 22 2024 at 04:52):

Hi there everyone , Is iasyswasma fs ready to use ?
I have a requirement to run concurrent programming on guest side in component model .

view this post on Zulip Afshan Ahmed Khan (May 22 2024 at 05:03):

Also which is the most simple test case in rust-cases to understand how I can use the guest and host for concurrent processing on guest side ? @Joel Dice

view this post on Zulip Afshan Ahmed Khan (May 22 2024 at 07:20):

I think the simplest example is round trip - I modified that example to get what I wanted to achieve . But got an error , I have filed an issue - https://github.com/dicej/isyswasfa/issues/4.
Can you guys help ?

I modified the round trip example like follows but I am getting error - wasm trap: cannot enter component instance I added below two static variables - // test/src/lib.rs static mut ROUND_TRIP: Opt...

view this post on Zulip Joel Dice (May 22 2024 at 13:46):

Hi @Afshan Ahmed Khan. isyswasfa is an experimental project which will become obsolete once proper async support has been added to the component model, which is what Luke Wagner and I have been working on (see my recent update here). Feel free to use it and report any issues you find, but keep in mind that I'll stop supporting it once the component model features are in a usable state.

Also note that you don't need isyswasfa or CM async if you only need to run simple components (i.e. components which have not been composed with other components). Instead you can just use a WASIp2-compatible runtime such as https://crates.io/crates/wasi-async-runtime or https://crates.io/crates/spin-executor if you're using Rust for the guest (and componentize-py has a built-in asyncio event loop for WASIp2 if you're using Python).

I'll leave a comment on the issue you opened, but the short answer is that the component model currently disallows reentering a component, meaning you can't call a guest export from a host import called by the guest. That's true for synchronous functions in the component model today and will continue to be true (AFAIK) for asynchronous functions as well. It's an interesting use case, though, so I'll discuss some alternative approaches in the issue.


Last updated: Dec 23 2024 at 12:05 UTC