dicej opened PR #11127 from dicej:cm-async-implementation to bytecodealliance:main:
This commit replaces the stub functions and types in
wasmtime::runtime::component::concurrentand its submodules with the working implementation developed in thewasip3-prototypingrepo. For ease of review, it does not include any new tests; I'll add those in a follow-up commit.Note that this builds on #11114 and #11123; only the third commit is new.
<!--
Please make sure you include the following information:
If this work has been discussed elsewhere, please include a link to that
conversation. If it was discussed in an issue, just mention "issue #...".Explain why this change is needed. If the details are in an issue already,
this can be brief.Our development process is documented in the Wasmtime book:
https://docs.wasmtime.dev/contributing-development-process.htmlPlease ensure all communication follows the code of conduct:
https://github.com/bytecodealliance/wasmtime/blob/main/CODE_OF_CONDUCT.md
-->
dicej requested wasmtime-fuzz-reviewers for a review on PR #11127.
dicej requested wasmtime-wasi-reviewers for a review on PR #11127.
dicej requested fitzgen for a review on PR #11127.
dicej requested wasmtime-core-reviewers for a review on PR #11127.
dicej requested wasmtime-default-reviewers for a review on PR #11127.
dicej updated PR #11127.
dicej updated PR #11127.
dicej requested alexcrichton for a review on PR #11127.
dicej updated PR #11127.
alexcrichton updated PR #11127.
github-actions[bot] commented on PR #11127:
Subscribe to Label Action
cc @fitzgen
<details>
This issue or pull request has been labeled: "fuzzing", "wasmtime:api", "wasmtime:c-api"Thus the following users have been cc'd because of the following labels:
- fitzgen: fuzzing
To subscribe or unsubscribe from this label, edit the <code>.github/subscribe-to-label.json</code> configuration file.
Learn more.
</details>
alexcrichton updated PR #11127.
alexcrichton updated PR #11127.
alexcrichton updated PR #11127.
alexcrichton commented on PR #11127:
@dicej on this one thing I want to write down before I forget (I've forgotten this many times so far...)
Index allocation for futures/streams/error-context I believe are going to need to be updated here. I believe the current state of this PR is such that there's one indexing namespace for all resources within a component, and then there's another index namespace for futures/streams/error-context. Spec-wise I believe it's required we unify these index namespaces. I realize that this is an artifact of the history of the implementation here, but it's something that I want to be sure to write down and not forget.
Effectively my naive expectation would be that this type grows to include
Stream/Future/ErrorContextvariants and a table or similar inConcurrentStatewill end up being removed.
alexcrichton updated PR #11127.
alexcrichton updated PR #11127.
alexcrichton updated PR #11127.
alexcrichton commented on PR #11127:
Another thought I've now had which I don't want to forget: this is introducing a significant
#[cfg]in the path of calling a component function with the async style. That means that the non-cm-async implementation will be entirely untested in CI which is not an ideal state to be in. I don't know how best to handle this but I wanted to note it before I forget.
alexcrichton updated PR #11127.
alexcrichton updated PR #11127.
alexcrichton updated PR #11127.
dicej updated PR #11127.
dicej edited PR #11127:
This commit replaces the stub functions and types in
wasmtime::runtime::component::concurrentand its submodules with the working implementation developed in thewasip3-prototypingrepo. For ease of review, it does not include any new tests; I'll add those in a follow-up commit.<!--
Please make sure you include the following information:
If this work has been discussed elsewhere, please include a link to that
conversation. If it was discussed in an issue, just mention "issue #...".Explain why this change is needed. If the details are in an issue already,
this can be brief.Our development process is documented in the Wasmtime book:
https://docs.wasmtime.dev/contributing-development-process.htmlPlease ensure all communication follows the code of conduct:
https://github.com/bytecodealliance/wasmtime/blob/main/CODE_OF_CONDUCT.md
-->
alexcrichton updated PR #11127.
alexcrichton updated PR #11127.
alexcrichton updated PR #11127.
alexcrichton updated PR #11127.
alexcrichton submitted PR review:
Ok I've gone through all of
concurrent.rsand here's comments here and there. I haven't looked atfutures_and_streamsyet and I'll want to closely review theunsafetraits there though, so more to come.I've also pushed up a few commits here for miscellaneous things, so feel free to squash them all in if you're ok with them or append further commits here.
alexcrichton created PR review comment:
IIRC this file is a duplicate of
vm/component/resources.rsright? (or at least a historic one). IIRC we talked about deferring resolving this duplication to later, but mind filing an issue and registering a FIXME here?
alexcrichton created PR review comment:
I manually changed the previous PR, but mind updating the import style in the new files to match the preexisting style in Wasmtime?
alexcrichton created PR review comment:
Mind either (a) resolving this TODO in this PR or (b) filing an issue for this TODO to point to and pointing to that?
alexcrichton created PR review comment:
Mind filing an issue for this?
alexcrichton created PR review comment:
Like above, can this be
pub(crate)
alexcrichton created PR review comment:
Can you file an issue about removing
to_vechere? I'm remembering now that while I synchronized the async/concurrent signature inLinkerfor dynamic things I think that's something we're going to want to do here as well forcall_concurrent. The signature will change slightly but I think it will still be doable (and like the linker ones it'd useVecinternally for now)
alexcrichton created PR review comment:
Could this be done by removing the task on
Dropinstead of allocating an extraArc?
alexcrichton created PR review comment:
Could this be made
pub(crate)?
alexcrichton created PR review comment:
Are these perhaps relics of a historical implementation? (similar with methods above). I'd otherwise imagine that the method-based accessors could all get removed in favor of accessing the fields directly
alexcrichton created PR review comment:
I'm wary of this in that we don't want to change the public API contract required depending on crate features being enabled or disabled. This implementation looks like it goes from requriing
post_returnto not requiring it, which would be a regression for the public API. Could this be integrated differently to still require post return whencall_asyncis used? (it's fine to me thatcall_concurrentis documented as not requiring post-return)
alexcrichton created PR review comment:
Mind removing this and replacing it with
Waker::noop()?
alexcrichton created PR review comment:
We'll want to do something about this (e.g. document, remove, etc).
In toying around locally though I see that the reason for this is
Vec<HostTaskFuture>which is onlySend, not alsoSync. I think we'll want to keep that in the sense that we don't want to require futures to all be bothSyncandSend, onlySend, if possible.Also in toying with this though I can remove the
spawned_tasksfield entirely and tests all pass. Given that do you know of a reason to keep this field, and if not can it be removed? (once removed it's possible to remove theseunsafe implblocks)
alexcrichton created PR review comment:
Also, mind running some of the basic, typed, no-call-hook, etc, benchmarks for host-to-wasm to see the impact of this new code path?
dicej submitted PR review.
dicej created PR review comment:
This is intentionally public to allow host function implementations to call
Instance::{future,stream}, for which they need anInstanceobject.Given that
InstanceisCopy, I suppose we could require the host function closure to close over anInstancefrom the top-level code (i.e. the code that actually creates the instance). The ergonomics wouldn't be as nice, though, plus it creates the hazard that the host embedder code mixes up itsInstances and closes over the wrong one.
dicej submitted PR review.
dicej created PR review comment:
See my reply above.
dicej submitted PR review.
dicej created PR review comment:
I think I just got carried away with writing accessor methods; I can get rid of them.
dicej submitted PR review.
dicej created PR review comment:
Also in toying with this though I can remove the spawned_tasks field entirely and tests all pass
Sounds like we're missing test coverage, then -- probably because we were leaning on the
wasmtime-wasi[-http]integration tests to exercise this and never wrote any non-wasi tests for it. I'm sure some of the wasi tests will fail if you remove that field.
dicej submitted PR review.
dicej created PR review comment:
Could this be done by removing the task on
Dropinstead of allocating an extraArc?I had originally planned to do that, but couldn't see how to avoid shared mutable aliasing of the store. Revisiting it now, I can see we just need a custom
Futureimplementation which has aStoreContextMutfield, similar to what we did forFiberFuture. I'll do that.
dicej created PR review comment:
BTW, I'm fine with changing the field to a
Mutex<Vec<HostTaskFuture>>if that's what we need to remove theunsafe impls.
dicej submitted PR review.
dicej created PR review comment:
Can you elaborate on how you'd like to see this code changed? Naively, I could imagine changing this to look more like
TypedFunc::call_async, but that would require the sameunsafeuse of a raw pointer, which I was trying to avoid here.
dicej submitted PR review.
alexcrichton submitted PR review.
alexcrichton created PR review comment:
Ideally we'd have
fn call_concurrent<'a>(self, store: ..., params: &'a [Val], results: &'a mut [Val]) -> Pin<Box<... + 'a>>where the returned future would close overparamsandresults. Internally that'd do something likeLinker::func_new_concurrentwhereVecis still used internally to satisfy the'staticneeded to put the future into the store but otherwise the public signature wouldn't change.
alexcrichton submitted PR review.
alexcrichton created PR review comment:
This sort of API makes it very similar to
Callerthat we have for core wasm which is something I've long wanted to delete from the public API, but it's pretty load-bearing so we probably can't remove that. I've historically wanted to resist any similar temptation to add such a similar call to components as well (e.g. there's noCalleron anycomponent::Linkermethods, it's all justStoreContextMut).I'll try to revisit this when reading over futures and streams code and see if I can't formulate more thoughts about this.
alexcrichton submitted PR review.
alexcrichton created PR review comment:
Currently in this PR there are no reads of the
spawned_tasksfield which is why tests in thecm-async-testsPR (which I realize doesn't includewasmtime-wasi{,-http}) pass. Does this mean that some changes from upstream wasip3-prototyping accidentally weren't merged back here?
dicej submitted PR review.
dicej created PR review comment:
Currently in this PR there are no reads of the
spawned_tasksfieldMaybe I'm misunderstanding, but isn't this a read of that field?
dicej updated PR #11127.
dicej updated PR #11127.
alexcrichton submitted PR review.
alexcrichton created PR review comment:
Er yes, bad words on my part. Basically nothing ever pushes on that vector so it's always empty
dicej submitted PR review.
dicej created PR review comment:
Ok, then yes, this looks like dead code. We used to push spawned tasks to a vector in
Access[or]::spawnbut now we callInstance::spawn_with_accessorinstead, so you're right that the field can be removed. I'll do that.
dicej updated PR #11127.
dicej updated PR #11127.
dicej submitted PR review.
dicej created PR review comment:
I've pushed an update to require
post_return_asyncforcall_asyncand added docs tocall_concurrentindicating that thepost-returnfunction is called automatically in that case.
dicej created PR review comment:
Also, mind running some of the basic, typed, no-call-hook, etc, benchmarks for host-to-wasm to see the impact of this new code path?
Would you mind providing instructions for doing that? I ran
cargo bench, but that ran a bunch of other, irrelevant stuff as well. How did you get your "before vs. after" numbers on the last PR, and how did you specify which ones to run?
dicej submitted PR review.
alexcrichton submitted PR review.
alexcrichton created PR review comment:
Oh sure yeah, I do:
cargo bench --bench call -- --listfirst, and then this accepts a regex argument to pare down what's being run so I build up a regex to just the benchmarks that are relevant. For example
cargo bench --bench call -- --list '^sync.*component'focuses just on sync calls (the fastest ones) and component-related ones. Here we only want host-to-wasm
cargo bench --bench call -- --list '^sync.*component.*host-to-wasm'and eventually what you probably want to run is:
cargo bench --bench call -- --list '^sync/no-hook.*component.*host-to-wasm.* typed .*'
alexcrichton submitted PR review.
alexcrichton created PR review comment:
What I'd also recommend is using
$previous_command --save-baseline mainon the
mainbranch or without the component-model-async feature. Then with this PR you'd run:$previous_command --baseline mainwhich will automate criterion reporting differences to the previously captured baseline
alexcrichton updated PR #11127.
alexcrichton updated PR #11127.
alexcrichton updated PR #11127.
dicej updated PR #11127.
alexcrichton updated PR #11127.
alexcrichton submitted PR review.
alexcrichton created PR review comment:
I think this wants to further type-check that the payload type matches
T, e.g.T::typecheck(...)
alexcrichton created PR review comment:
Would it be possible to change all these
watch_*methods toasync fn watch(&mut self) { ... }? That I think is a simple signature to model the various interactions here:
- By taking
&mut selfit's effectively "taking ownership", aka preventing anything else happening.Watch::into_inneris now dropping the returned future.
alexcrichton created PR review comment:
Here "write end dropped without writing" is a documentation-of-eld, right?
alexcrichton created PR review comment:
Along the lines of a comment about
async fnabove, I think this would be much clearer as a loop over the buffer callingself.writerather than via recursion.
alexcrichton created PR review comment:
Wherever possible I personally find it much easier to reason about/read
async fnsignatures rather than those returningimpl Future. Would it be possible to change this, and a number of other functions in this file that just returnimpl Futuretoasync fn? I believe theSend-ness of the future here will be correctly inferred.
alexcrichton created PR review comment:
Like writers above, could this be an
async fnwith&mut selfas a receiver?
alexcrichton created PR review comment:
Similar to above the payload here needs to be type-checked against
T
alexcrichton created PR review comment:
Similar to futures above I think this
repneeds to be type-checked againstT
alexcrichton created PR review comment:
This trait, and
ReadBufferbelow, show up in public trait bounds so these need to be public documented traits. Ideally with links to what methods use them and such.
alexcrichton created PR review comment:
Would it be possible to have this be
&mut self? I realize that would mean changing how "things are dropped" is modeled but personally I find that style of ownership much easier to work with than the move-in-and-move-out style this is currently using.
alexcrichton created PR review comment:
FWIW I find the terminology here pretty confusing. I understand you pass a
ReadBufferto a read operation, but the only thing you can do with aReadBufferis write to it. I have not spent much time trying to find better names, but I wanted to write this down nonetheless.
alexcrichton created PR review comment:
My understanding is that this is not intrinsic to the feature, is that right? This is only here for the
{Take,Read,Write}Bufferimplementations?If so can this be made an optional feature to avoid requiring it?
alexcrichton created PR review comment:
There's no protections here that
Tis correct?
dicej updated PR #11127.
dicej submitted PR review.
dicej created PR review comment:
I've replaced the
Arcwith code that removes the task when the future is resolved or dropped. I've also opened https://github.com/bytecodealliance/wasmtime/issues/11209 to track future optimization work.
dicej updated PR #11127.
dicej created PR review comment:
Issue filed: https://github.com/bytecodealliance/wasmtime/issues/11218
dicej submitted PR review.
dicej submitted PR review.
dicej created PR review comment:
Issue filed: https://github.com/bytecodealliance/wasmtime/issues/11219
dicej submitted PR review.
dicej created PR review comment:
Issue filed: https://github.com/bytecodealliance/wasmtime/issues/11219
dicej submitted PR review.
dicej created PR review comment:
Issue filed: https://github.com/bytecodealliance/wasmtime/issues/11219
dicej submitted PR review.
dicej created PR review comment:
Issue filed: https://github.com/bytecodealliance/wasmtime/issues/11219
dicej submitted PR review.
dicej created PR review comment:
Yeah, I struggled with the names of
WriteBufferandReadBuffer, too. What aboutSourceBufferandDestinationBufferinstead?
alexcrichton created PR review comment:
I'm going to defer this to https://github.com/bytecodealliance/wasmtime/issues/11223
alexcrichton submitted PR review.
dicej submitted PR review.
dicej created PR review comment:
I've opened an issue for this: https://github.com/bytecodealliance/wasmtime/issues/11222
dicej submitted PR review.
dicej created PR review comment:
I've opened an issue for this: https://github.com/bytecodealliance/wasmtime/issues/11222
dicej submitted PR review.
dicej created PR review comment:
I've opened an issue for this: https://github.com/bytecodealliance/wasmtime/issues/11222
dicej submitted PR review.
dicej created PR review comment:
Issue filed: https://github.com/bytecodealliance/wasmtime/issues/11219
dicej submitted PR review.
dicej created PR review comment:
I've opened an issue for this: https://github.com/bytecodealliance/wasmtime/issues/11222
dicej submitted PR review.
dicej created PR review comment:
Issue filed: https://github.com/bytecodealliance/wasmtime/issues/11226
dicej created PR review comment:
Issue filed: https://github.com/bytecodealliance/wasmtime/issues/11226
dicej submitted PR review.
alexcrichton submitted PR review:
Ok I believe we've filed issues for follow-up tasks but otherwise this is an off-by-default feature and in a pretty good spot otherwise, so I'm going to flag for merge. Thanks again @dicej!
alexcrichton merged PR #11127.
Last updated: Dec 06 2025 at 07:03 UTC