Stream: wasi

Topic: WASIp3 async fallibility & wRPC


view this post on Zulip Pavel Šavara (Nov 19 2024 at 15:48):

I would like to discus few failure scenarios around futures and streams.

let's assume function add: func(a: u8, b: u8) -> u8;

I think that when you consume p3 method as async, the future/promise/Task you get could be rejected/failed by producer side and the caller will receive error-context which they could handle, right ? This is nice.

A) I would like to understand what happens when producer component exports it as async, therefore fallible and consuming component imports it as synchronous, therefore un-fallible. What happens to consumer when the producer rejects the promise ? Is the consumer instance going to trap/abort ?

B) It could also happen that the implementation would be virtualized by wRPC, which would introduce failures (of networking) into this contract.

Easy answer would be to proclaim that we should always consume imports as async, when we know that it could be remote. This forces async "color" to your functions. It also introduces unexpected latency.

But that's not an answer for sync components that get dependencies remote-virtualized unknowingly.

I'm worried that in this way wRPC is introducing impedance mismatch in DCOM way.

cc @Luke Wagner @Joel Dice @Roman Volosatovs

view this post on Zulip Lann Martin (Nov 19 2024 at 16:31):

My understanding is that error-context is used with streams/futures but not tasks. Tasks themselves can only fail by returning an explicit error result or trapping.

view this post on Zulip Pavel Šavara (Nov 19 2024 at 17:14):

I was thinking C# Task in text above as marshaled from future. Sorry for confusion.

view this post on Zulip Roman Volosatovs (Nov 19 2024 at 19:03):

In context of wRPC, the bindgen generates a fallible signature (e.g. your add function import would return anyhow::Result<u8>)

If any async value is used in import in either parameter or result tuple, the bindgen will return an additional value - an I/O driver - a future, which must be polled - that future may fail (IIRC with std::io::Error directly)

view this post on Zulip Pavel Šavara (Nov 19 2024 at 19:09):

So, wRPC is not usable as virtualization of existing WIT ?

view this post on Zulip Roman Volosatovs (Nov 19 2024 at 19:12):

wRPC is a general-purpose RPC framework, it's not anyhow specific to WebAssembly. It is built on WIT though, so being able to use existing WIT is precisely the use case.

Not sure exactly what you're asking.

If we're talking about "polyfilling" Wasm component imports, then RPC protocol choice here seems pretty arbitrary and hiding fallible network I/O underneath it is a bad idea regardless of the RPC protocol chosen

view this post on Zulip Roman Volosatovs (Nov 19 2024 at 19:14):

Generally, you would want a local entity exporting an interface (a host plugin) and converting the transport layer errors into application layer ones

view this post on Zulip Pavel Šavara (Nov 19 2024 at 19:19):

Roman Volosatovs said:

If we're talking about "polyfilling" Wasm component imports, then RPC protocol choice here seems pretty arbitrary and hiding fallible network I/O underneath it is a bad idea regardless of the RPC protocol chosen

Thank you for clarifying, I was not clear if this is/was the design intent. That solves my worry about B).

Is there separate wit-bindgen mode/version that is doing the wrapping as anyhow::Result<u8> ?

view this post on Zulip Roman Volosatovs (Nov 19 2024 at 19:21):

wRPC has a custom bindgen. There are also some optimizations in place for remote use cases

wRPC bindgen tries hard to match the API of wit-bindgen, which is why wRPC repo merges from wit-bindgen tree

view this post on Zulip Pavel Šavara (Nov 19 2024 at 19:59):

I'm thinking that in languages which support exceptions, fallibility could be solved without changing the signature.

In rust, generating anyhow::Result<u8> is also solution for problem A) ? Is that what it does in WASIp3 wit-bindgen ?


Last updated: Dec 23 2024 at 12:05 UTC