Live data from Hacker News

WASI 0.3

bytecodealliance.org

61–70 of 103 posts

Re: WASI 0.3

#61
post #38

Earlier quoted context omitted.

I disagree. We shouldn't just be copying Unix until the end of time.

less copying and more keeping in the spirit of, as it has clearly shown it is a model that is built to last

Unix is completely inapplicable to this environment which is inherently managed and intraprocess. Why not send an object saying what you want instead of a plain C struct, or worse a bunch of ints? How do we handle ownership across these boundaries? Why should two high level components be forced to squeeze into a primitive bottleneck between them?

Don't get me wrong: I think C is cute and fills a niche decently well. But that niche is not the one we have here.

The reasons why Unix displaced a bunch of more elegant systems were downward scalability, free distribution, and positioning to take advantage of network effects. Quality was secondary, especially with multiprocessing and networking where a lot had to change, and the designs were not always good.

Re: WASI 0.3

#62
post #40

Earlier quoted context omitted.

> - "What is a Component (and Why)?" (WasmCon 2023): https://www.youtube.com/watch?v=tAACYA1Mwv4 At 18:00 the speaker states something like "It should not be Systems Interface but Standard Interfaces" which honestly sounds like a different project. As an implementer or even as just a user in general, can it be trusted that tomorrow it isn't something completely different? Seems like an odd standard to follow. (EDIT a…

The speaker is right. Why should "system" interfaces and interfaces from other components ever be fundamentally different?

I get that. That's not my criticism. My criticism is that you can do say that about many things. With that argument you can essentially encompass everything, which is cool in a way, but also means that the scope is at least bigger than the original - hence what the speaker says.

What I worry about here is that when I think about implementing it the scope will likely grow as well. And while I very much get the wish to encompass things in a standard (I think everyone who ever wrote any kind of specification knows that) a standard doing that extension when the initial goal of being a (commonly used) system interface isn't achieved - at least that's how'd interpret being 0.3 now - then what if that scope extends like that. Will we see full implementations?

To me it seems like maybe it would have made sense to separate that a bit. Something like a WASI based standard. Or something else. The fact that you almost need to change your name like this indicates that you went quite a bit away from the initial goal and doing that before a 1.0 seems like a very early point to get of course for any project. Sure sometimes you find out that you have looked at it from the wrong angle, but honestly this doesn't look like it. This looks a lot more "this is something we can reuse".

Re: WASI 0.3

#63
post #12

If you have used WASI in the past, can you mention your use case? Very curious if you found it to give you an edge compared to other sandboxing like containers or VMs.

> If you have used WASI in the past, can you mention your use case?

For my "TagLib for TypeScript" library, I use WASI for local filesystem operations when used with Node.js/Deno/Bun. https://github.com/CharlesWiltgen/taglib-wasm

Re: WASI 0.3

#64
post #12

If you have used WASI in the past, can you mention your use case? Very curious if you found it to give you an edge compared to other sandboxing like containers or VMs.

[dead]

Re: WASI 0.3

#65

Wrong direction. WASI should be simple and stable. Initially, it was revolving around a simple Unix-like API model and it was close to perfect. Now, there is an opinionated component model which is an unneeded overcomplication that should have never been considered as part of WebAssembly spec IMHO. A real component model is a separate development and cannot be blindly tied to a particular ecosystem. Otherwise, its ma…

> WASI should be ... stable.

The WASI standard is not at 1.0 yet! The people designing WASI are still trying to figure out what people want WASI to be at this point.

This is very likely to involve a lot of major reworking before 1.0, in response to feedback from orgs actually trying to implement WASI-based WebAssembly embeddings into their systems and runtimes. 0.1.x -> 0.2.x was one reworking; 0.2.x -> 0.3.x is another. There may be more of these before an approach is finally settled upon / "locked in" for 1.x.

---

> Let's keep WebAssembly lean and fast!

AFAICT, the entire point of the changes (incl. the more detailed component model) in WASI 0.3 is performance. Not performance of WebAssembly as a black box, though; but rather, performance of the running system as a whole, when a lot of FFI traffic is flowing across the WASI boundary. The richer component model enables lower impedance mismatches and "thinner" FFI-layer implementations.

For example, from the OP:

> WASI 0.2 handed you an output-stream that you wrote into imperatively. WASI 0.3 has you pass in a stream and get back a future that resolves when the write completes.

For some host languages/runtimes, "imperative blocking write calls" is already how writes against IO descriptors are exposed to the programmer. For those languages, WASI 0.2 made sense.

But in other host languages/runtimes, writes against IO descriptors are inherently non-blocking, returning promises or yielding. For those languages, WASI 0.2 "left performance on the table." WASI 0.2 required such languages to implement a blocking IO write abstraction on top of their non-blocking IO write semantics, in order to pass that blocking-IO-write primitive into the WebAssembly componennt... even if the WebAssembly component was internally concurrent (e.g. compiled from a language like Golang) and so would highly benefit from a non-blocking-IO-write primitive!

Meanwhile, if you require that the host expose a non-blocking-IO-write primitive (as WASI 0.3 does), then for hosts with native non-blocking IO, doing so is free; while for hosts with only blocking IO, non-blocking IO can be "faked" basically for free (i.e. with a global or per-resource linearized write queue on the host side.) And likewise, non-blocking-IO-aware WebAssembly components can freely take advantage of NIO; while WebAssembly components that expect blocking IO only need the tiniest added bit of a codegen shim (`blocking_write(x) => await nonblocking_write(x);`) to fit into a WASI 0.3 world.

In other words, implementing nonblocking IO abstractions on top of blocking IO abstractions costs FFI performance, but implementing blocking IO abstractions on top of nonblocking IO abstractions is "free" (in FFI terms.) Nonblocking IO should therefore be considered the more "primitive" of the two; and so, if you have to choose only BIO or NIO to expose as a capability across a boundary to an unknown peer, NIO should be the one you choose.

---

That being said...

The WASI devs were likely aware of the "FFI optimization opportunities being left on the floor" in WASI 0.2. They likely already wanted to take things in this direction from the beginning. But in WASI 0.2, without async, it was impossible to express the concept of nonblocking IO (i.e. of IO operations returning a promise/future.) They needed to introduce this more "opinionated" (i.e. richer) component model in order to get here.

AFAICT, WASI 0.2 was never intended to be a Release Candidate of the WASI spec. (And WASI 0.3 likely isn't either!)

Rather, WASI 0.2 had areas (like IO) that were purposefully left "under-baked". The WASI team knew people needed some version of these primitives in order for WebAssembly components to usefully integrate into systems at all. But they hadn't yet put in the work on designing how certain aspects of WASI (e.g. async) would work. So they designed WASI 0.2 as a prototype design, based on the limited toolbag of primitives they had already fully agreed upon. Some aspects of WASI turned out to only "want" that limited toolbag of primitives, and so didn't change at all under WASI 0.3 (and might even be in their final shapes.) Other aspects "wanted" things that weren't there, and so experienced over-constrained designs under WASI 0.2, replaced with less-constrained designs under WASI 0.3.

I fully expect there will be more such changes under WASI 0.4. If you don't want to be a guinea pig for major WASI changes, you might want to wait for WASI 1.0. (However long that takes.)

Re: WASI 0.3

#66
This is funny timing to me, because just the other week I did a dive into WebAssembly and WASI 0.2 (https://jsdw.me/posts/wasm-components/) and assumed that 0.3 would be a while yet as there was no obvious (to me) sign it would come for a while!

Once the tooling is there and Rust has a wasi 0.3 target I'll give it more of a look at :)

Re: WASI 0.3

#67
post #12

If you have used WASI in the past, can you mention your use case? Very curious if you found it to give you an edge compared to other sandboxing like containers or VMs.

I used WASI to compile an existing 1990's 8-bit assembler cmdline tool written in C for use in a VSCode extension (https://marketplace.visualstudio.com/items?itemName=floooh.v...) - along with regular browser-based WASM compiled via Emscripten for the embedded emulators.

For this use case the old-school POSIX-style WASI was just perfect and completely hassle-free via the WASI SDK (https://github.com/webassembly/wasi-sdk).

Not sure what to think of all the bells and whistles that were added afterwards (esp the component model), the very first WASI standard was the perfect sweet-spot of simplicity and usefulness. I'm pretty sure I'll never need any of the things that were added afterwards (and I'm going to be slightly pissed when the simple use case - building and running POSIX code - gets more complicated).

Re: WASI 0.3

#68
post #11

Love/hate with this one. How was I supposed to follow this? I tried, and few things were publicly visible for nearly two years. I last checked in march and it looked like no progress had been made. That makes me very suspicious of wasiv3. Funny enough, I already implemented a bunch of the promises (pun not intended) and think that freestanding wasm with custom integrations is the more likely future. The promise of wa…

> The promise of wasi components has not been fulfilled. The market wants to hotload and link artifacts dynamically. The wasi project requires insider wizardry to use it that way: the offering has been statically linking components before you ship. Defeating 99% of the use cases.

I think both of these points on the spectrum (on the one end, fully static linking of WASI components within a monolithic single-source project; and on the other end, dynamic-at-runtime compiling + linking + loading + "hot instantiating" of arbitrary black-box WASI-component artifacts, with dynamic [presumably reflection-based?] API discovery to drive interaction with those components) are strawmen. There are relatively few "real" use-cases for WASI on either of these ends.

Most of the stuff anyone is really interested in using WASI for (AFAICT, from the use-cases for it I've seen in the wild) involves something closer to the midpoint between these two points. Somewhat dynamic and modular, but with no JIT compilation / components-fetching-components / hot component instantiation / dynamic reflection stuff going on.

Specifically, the "point" of WASI (in my opinion, and in the opinion of most people I've spoken with about it), is to serve as a sort of meta-standard (with tooling) for concrete "pluggable runtime" systems to implement plugin-support SDKs in terms of.

In such "plugin ecosystems", every "plugin" (WASI component) is of the same shape (i.e. exposing the same endpoints, and expecting the same capabilities.) And so the host runtime, and each of its plugins, can be precompiled (separately, in separate projects!) against that shape. And the plugin host can load arbitrary wasm components into a pre-baked plugin "slot" at runtime, because there's no dynamism / introspection / reflection / component framework support required or involved. The plugin host isn't a component itself; it's just ordinary host runtime code, written once. The component framework doesn't load the component; the host runtime does. Etc.

In a sense, this is "custom binding" as you were talking about. But it's custom binding against a WASI-specced target; which is what enables different plugins to be runtime-fungible within the same plugin "slot" from the host's perspective. (While giving you sandboxing for free, unlike the traditional "a plugin is just a DLL that exports certain symbols" approach.) WASI does all the work plugin hosts want of it at component compile/link time: verifying that the plugin is of the expected ABI shape, and guaranteeing sandboxing (by a WASI component inherently being a thing developed to run as an isolate under an abstract machine.) The fact that a compiled+linked WASI-component artifact is a blob of WebAssembly built against certain WIT interfaces, isn't just something tagged onto it by external metadata; it's also something inherent to the structure of the resulting artifact, i.e. a property determinable via static analysis.

At runtime — or slightly earlier, at plugin "install" time — a plugin host might not even keep the component as a component. It might preprocess it into a DLL, or whatever its runtime's equivalent of a DLL is. (A Java class file, say.) The crucial thing was that the component was a component when it was handed off from the downstream developer to the plugin host. Because then any code generated to wrap the component into a host-runtime-native module, is code trusted by the host, rather than code controlled by the downstream developer.

---

If your goal is to compile some one-off blob of WebAssembly code into an artifact that you can then e.g. treat like an old-school ActiveX component from browser JavaScript, then yeah, you don't need WASI at all for that. You're not trying to create a plugin ecosystem. You don't need to spec out a standard "socket" for downstream devs to plug into. You're just "plugging X into a thing that expects only and exactly X". So skip WASI; just use a one-off custom binding. (Though I would note that the WASI work has acted as a forcing function for the WebAssembly-component ABI, enabling you to write much richer custom bindings than you would have been able to write before WASI.)

But if you're:

- developing a FaaS runtime like Cloudflare Workers

- developing a game engine that allows "mods"

- developing a cloud-hosted agent sandbox, where the toplevel is code (that invokes LLMs, that invoke capabilities)

- developing a modern replacement for Wordpress, with an aim to allow just as much extensibility but to not repeat Wordpress's endless vulnerabilities

(etc)

...or, in other words, if you are developing an application or service that O(N) downstream-developed things (workloads, plugins, mods, extensions, whatever you want to call them) all plug into; where you want these things to all plug into your host system in a very precise and controlled way, rather than being given free rein to touch anything they want; and where these interaction patterns can all be described in one of a few very specific shapes, with a precisely definable spec for 1. what API the runtime wants to call into on the component; and 2. what APIs the runtime wants to hand to the component, to enable the component to call those APIs...

...then WASI was developed precisely for you.

And, more specifically, WASI was created so that you could:

1. use WASI to define that API spec (as machine-readable WIT files); and then

2. give that spec, and those WIT files, to the developers in your ecosystem;

3. so that they could then use existing WebAssembly+WASI tooling to build WebAssembly components that target your API spec. (Most likely not by expecting them to independently bootstrap a WebAssembly+WASI dev environment; but rather, by you shipping an SDK that embeds WebAssembly+WASI tooling and your WIT files together.)

(I would also note that this — i.e. "the thing WASI solves for" — is actually a rather rare use-case on the whole. Your average dev isn't [and shouldn't be!] building an ecosystem for API-sandboxed plugins of their code. The few devs that do need to construct their own plugin ecosystems around their project, probably can therefore be expected to go quite deep on learning any required "insider wizardry." If that was even required. Which it generally isn't, when all you're trying to do is to load one of N unknown-until-runtime but statically-defined-ABI-shape plugin components; rather than trying to load arbitrary runtime-generated dynamically-defined-ABI-shape components, allowing those components to load or compile+exec further components, etc.)

Re: WASI 0.3

#69

Will WebAssembly ever achieve a real breakthrough? It's been almost 10 years since it came around. HTML, CSS and JavaScript were a breakthrough back in the days. WebAssembly still is not right now; only very few folks or companies use it.

for me its undebuggability. -"hey, look at our C Rust FORTRAN to WASM translator, blahblah" -"uhm, cool, how do I debug it?" -"yeah...about that...you cant!"

Wasmtime implements a remote debugging server, so that you can debug guest programs with a recent build of LLDB. Set breakpoints based on the source language symbols, single-step through wasm opcodes, anything you'd expect: https://docs.wasmtime.dev/examples-debugging-guest.html

Re: WASI 0.3

#70
post #59

Hey everyone, we just published the announcement post for WASI 0.3 on the Bytecode Alliance blog: https://bytecodealliance.org/articles/WASI-0.3 The current link is just the release notes and covers only the interface-level changes. The announcement post goes into more detail on what's new in WASI 0.3, how it differs from WASI 0.2, and includes examples.

Ok, I've swapped that link in at the top and put the submitted URL (https://github.com/WebAssembly/WASI/releases/tag/v0.3.0) in the toptext.
Post reply on HN