runtime-wasmtime: bridge wasi:io streams to stream<u8>#1262
Open
cargopete wants to merge 1 commit into
Open
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #185.
Closes #184 (the async-path computation over Wasmtime component types is exactly part 1 below).
wrpc-runtime-wasmtimeis meant to send/receivewasi:ioinput-stream/output-streamresources as native wRPCstream<u8>. Most of the machinery existed but was untested; this PR makes it work end-to-end and adds a runnable example.Bugs fixed
Three distinct issues were blocking the path, found by building the example below and following the failures:
Subscription paths were never set. Both
serve_functionandserve_function_sharedcalledself.serve(.., [])(the two// TODO: set pathsmarkers), so the transport never subscribed to a stream parameter's data channel — invocations failed with`[0]` subscription not found. Addedpaths::params_async_paths, which walks the Wasmtime component parameter types (mirroringwrpc_introspect::async_paths_ty) and computes the async subscription paths, treatingwasi:iostreams asstream<u8>.wasi:iostream resources were misclassified during decode/encode. At serve time a stream parameter appears as the component's uninstantiated resource type, which does not equalResourceType::host::<DynInputStream>(), so the codec fell through to the guest-resource branch and tried to read a resource handle instead of stream data. The runtime now collects the component's importedwasi:io/streamsresource types up front (paths::wasi_io_stream_resources) and threads them intocall/read_value/ValEncoderso streams are recognized regardless of instantiation state.Created input streams carried the wrong resource type. The decode path pushed
Box::new(AsyncReadStream::new(..)), whose inferred type was the concrete reader rather thanDynInputStream, sotry_into_resource_anytagged the handle with a type that failed the guest'sown<input-stream>check (mismatched resource types). Annotating it asDynInputStream(as wasmtime-wasi itself does) fixes the handle type.Example
Adds
streams-io-component-server(a reactor component exportingcount: func(data: input-stream) -> u64, reading the stream viawasi:io) andstreams-io-tcp-client(a peer that invokes it with a native wRPCstream<u8>).The component reads its parameter purely through
wasi:io/streams; the runtime bridges it to/from the wirestream<u8>transparently.Notes
// TODO: Implement a custom readercomment incodec.rsis left in place: the receive side still relies on the transport sub-reader reaching EOF rather than consuming the\0stream terminator explicitly. This works for the TCP transport (verified for empty, single-byte, and multi-byte payloads) but the deeper terminator handling is left as follow-up.polyfillpath passes an empty stream-resource set, preserving its existing host-type-only behavior (no functional change there).