Stream: general

Topic: wasm support in my data processing engine


view this post on Zulip eirikb (Jul 13 2024 at 14:03):

Hi. I have an engine that let my users pre-process data going into a HTTP API. For example if someone POST an item with firstName and lastName they can write a simple snippet to concatenate this into a new fullName field. I use deno_core to run their code in a sandbox. They run in a context where item is a globally available variable, which they can read and write to. Something like this:

item.fullName = item.firstName + ' ' + item.lastName;

This works fine, and with this I have support for both JS and TS.
But with wasm I could in theory add support for a bunch of other languages and cool features.
I thought this would be easy, just let people send in a wasm module instead of JS and I pass in the item. But it turns out it is a bit more complicated in wasm world.
Any suggestions on how to make this as pleasant for my users as possible (the people making the modules)?
Everything I've tried so far, of wasmtime, assemblyscript, kotlin, c++ etc. is not very language agnostic, it seems there is not even an agreement on what a string should look like.
This made me look into compoment model and WIT. But I'm not sure it does what I really want.
WIT seems like what I want, but the truth is that host system doesn't actually know the item type, it just passes JSON. This made me think I could let end users bundle in JSON parser/writer in their wasm and do JSON in and out. But even that won't work if a string isn't common.
Perhaps WIT with just string in/out? And shouldn't compoment model without WIT define a string?
Using very new features is not a problem, it is better for users to wait for proper support in their language than some home-made solution.
Any suggestions? I'm a bit lost :sweat_smile:

A Cargo subcommand for creating WebAssembly components based on the component model proposal. - bytecodealliance/cargo-component

view this post on Zulip Pat Hickey (Jul 15 2024 at 04:32):

wit and the component model aren't distinct topics - the component model defines the binary and text encoding for components, which includes component types (as opposed to the core wasm types) for string, records, variants, resources and so on. components have a s-expression wat representation just like core wasm, but that representation isnt really human-friendly for reading or writing, so the wit syntax is an alternative representation of component types that is meant to be easily read and written

view this post on Zulip Pat Hickey (Jul 15 2024 at 04:33):

strings are a primitive value type in the component type system https://github.com/WebAssembly/component-model/blob/main/design/mvp/Binary.md#type-definitions

Repository for design and specification of the Component Model - WebAssembly/component-model

view this post on Zulip Pat Hickey (Jul 15 2024 at 04:36):

if the host system passes unstructured json, then you should just use a component model string to pass that to/from your components

view this post on Zulip Pat Hickey (Jul 15 2024 at 04:38):

if the json is actually structured and can be described using the wit concepts of array, record, variant etc, then you could write that structure down in a .wit, and have the host system parse it into that structure, and pass the structure to/from components.

view this post on Zulip Pat Hickey (Jul 15 2024 at 04:39):

if you havent yet read https://component-model.bytecodealliance.org/ it may help, but you are welcome to ask more questions here too

view this post on Zulip eirikb (Jul 15 2024 at 07:45):

Thank you for the answer.
I was a bit put off by all the code generation (wit-bindgen and jco), and I had issues running wit-bindgen because of required "--with" argument. Found an issue on that on GH, installing from main branch fixed it.

I'm going to have some helper methods on host side, such as "log" and "get" (simplified fetch). So I think WIT would be a perfect fit.

I did a test now where I started with a plain rust lib, wrote my own WIT, generated with wit-bindgen and built with cargo-component.
Then I generated JS with jco from the wasm file, wrote a simple test script and ran that in node.
It all worked as expected.
I'm not going to run in node, my host is rust, I just needed some platform where it was easy to test.
jco created module imports for my host functions so that didn't go as expected, but could be I did something wrong or it won't work like that in rust.

view this post on Zulip Pat Hickey (Jul 15 2024 at 17:07):

if your host is in rust then you should use wasmtime to execute the component created by jco componentize

view this post on Zulip Pat Hickey (Jul 15 2024 at 17:07):

for host bindings generation, you'll use wasmtime::component::bindgen!

view this post on Zulip Pat Hickey (Jul 15 2024 at 17:10):

https://docs.rs/wasmtime/latest/wasmtime/component/bindgen_examples/index.html

view this post on Zulip eirikb (Jul 17 2024 at 10:42):

Thank you. I've been playing around with this, but I'm struggling to return strings.
In WIT:
export yo: func() -> string;
In code:

    fn yo() -> String { "yo".to_string() }

But when I consume the wasm from this in a rust runtime I get:

Error: component imports instance wasi:cli/environment@0.2.0, but a matching implementation > was not found in the linker

Caused by:
0: instance export get-environment has the wrong type
1: function implementation is missing

view this post on Zulip Pat Hickey (Jul 18 2024 at 17:50):

https://docs.rs/wasmtime-wasi/latest/wasmtime_wasi/fn.add_to_linker_sync.html


Last updated: Nov 22 2024 at 17:03 UTC