Hello,
I’m new to wasmtime and I could use some help.
I want to port a module that creates TCP sockets to wasmtime. I understand it must use the wasi-sockets API.
So I wrote a minimal test that calls the wasi:sockets/tcp-create-socket@0.2.0/create-tcp-socket() function.
And then I do:
wasm-tools component new testapp.wasm --adapt wasi_snapshot_preview1.command.wasm -o testapp-p2.wasm
But it stops with the following error:
error: failed to encode a component from module
Caused by:
0: failed to register indirect shims for main module
1: missing component metadata for import of wasi:sockets/tcp-create-socket@0.2.0::create-tcp-socket
I know the name and type of the function are good, because if I change them, I get another error like “type mismatch for function create-tcp-socket
: expected [I32, I32] -> []
but found [I32, I32] -> [I32]
”. So the tool knows about that function, but doesn’t want to include it.
If I extract the WIT information with “wasm-tools component wit”, the wasi:sockets/tcp-create-socket@0.2.0 module is not there. Maybe this is why. But how to add it? I can extract WIT, but how can I modify it and then update the WASM file with the new version?
when wasm-tools component new says "missing component metadata for import" what that means its looking for information in a custom section that provides component model type information for the module-level import
when you use the wit-bindgen tool suite for various languages, this information ends up in your linked module on your behalf, unless you are using wit-bindgen c, in which case it emits it in a special .o
file that you need to pass to cc as part of your linking step. are you by chance using wit-bindgen c?
If I don't call functions from wasi-sockets
, the wasm-tools component
command completes, and the WASM file runs. For example if I call wasi:cli/stderr@0.2.0/get-stderr()
it works and returns the descriptor. But not for functions from wasi-sockets
.
I don't need to export anything to other components.
I use Kotlin and Zig. I installed wit-bindgen-cli to see what the .o file you are talking about contains. It requires a WIT file, but with the one from my test app it prints "Error: package not found import wasi:cli/exit@0.2.0;"
I tried this:
package testapp:component;
world testapp {
import wasi:sockets/tcp-create-socket@0.2.0;
}
But got "Error: package not found" even with a copy of tcp-create-socket.wit
in the same directory.
Error is the same with teavm-java
The default WIT content is:
package root:component;
world root {
import wasi:cli/exit@0.2.0;
import wasi:io/error@0.2.0;
import wasi:io/streams@0.2.0;
import wasi:cli/stdin@0.2.0;
import wasi:cli/stdout@0.2.0;
import wasi:cli/stderr@0.2.0;
import wasi:clocks/wall-clock@0.2.0;
import wasi:filesystem/types@0.2.0;
import wasi:filesystem/preopens@0.2.0;
export wasi:cli/run@0.2.0;
}
How to add wasi:sockets to that list and remove the imports I don't need?
Also why are imports required? With function calls, the WASM file already contains what modules, versions and functions must be imported. Why the duplication? Is it for IDEs?
the type information for all of those imports is coming from the adapter, but the adapter doesnt have the type information for wasi sockets
those imports are present because the adapter requires them in order to provide an implementation of wasi preview 1 to your module
if you dont need them, you can take a look at the adapter source for how we narrowed it down for the proxy build, and try that, but its not trivial. we havent put much energy into optimizing the way the adapter builds because its 1. quite difficult, and 2. a stepping stone to where toolchains use the preview 2 imports directly
if you are using kotlin and/or zig you'll have to provide the component type information for the preview 2 functions your module imports in order to use wasm-tools component new
. you can dig into how the wit-bindgen c object file creator works in that project to see how.
But what WIT file shall I give to wit-bindgen c
? What should it contain to enable wasi sockets? What is "the component type information" exactly? A custom section? Functions that have to be defined?
I just want to call a function. Why is it so complicated?
Can the adapter be patched to include wash-sockets
?
Is it possible to buy support for wasmtime to help us solve that issue?
Or any other place to ask for help?
you should invoke wit-bindgen c with the wasi-cli command world. its complicated because this is brand new stuff and nobody has yet built out a super easy DX for your language. it will only feel simple once that happens.
i'm not aware of anyone offering commercial support for wasmtime or other places to ask for help. this is a small community and this zulip is the center of it.
Could you clarify what "the wadi-cli command world" is? What should the content of the file be? Is it a copy of https://github.com/WebAssembly/wasi-cli/blob/main/wit/command.wit and imports.wit
patched to include wasi-sockets
?
Kotek said:
I just want to call a function. Why is it so complicated?
Reading over this I wanted to point out that comments like this generally aren't too helpful and end up more often than not being actively harmful. As a maintainer it's difficult to see comments like this in the sense that while we understand documentation and the tooling isn't perfect a comment like this indicates that you might not be acting in good faith and/or not be putting in the effort to engage with us trying to help.
I haven't read over the rest of the thread here but I wanted to at least point that out. We always appreciate help in fixing issues, improving docs, or even just help identifying what needs improvement. It's best though to assume everyone's acting in good faith here and it's not like we're intentionally making things hard, but instead this is somewhat of a new ecosystem and it takes time to grow it.
I agree with what Alex said here, so the best path is to start again with the idea that this is a new path for us all.
We are with your desires here. Help us keep you and others get to the right path.
The community has arrived at this place, hoping to make it easier - but we aren't quite here yet. Help us help you.
hi, i just tried using a socket from wasmtime and ran into an error saying that sock_open
doesn't exist. that led me down the path of finding out that wasmtime doesn't support WASIX. is there any recommended way of doing IPC with WASI / wasmtime?
wasip2 has support for opening sockets. Wasip1 (which you presumably are using and which wasix extends) also supports sockets, but sockets that are pre-opened by the host. Wasip1 doesn't allow you to open new sockets at runtime. For that you have to use wasip2.
awesome, thanks!
Last updated: Dec 23 2024 at 12:05 UTC