Skip to content
This repository was archived by the owner on Nov 25, 2025. It is now read-only.

feat: add wasi-0.3.0 draft#111

Merged
badeend merged 37 commits intoWebAssembly:mainfrom
rvolosatovs:feat/0.3.0-draft
Jan 21, 2025
Merged

feat: add wasi-0.3.0 draft#111
badeend merged 37 commits intoWebAssembly:mainfrom
rvolosatovs:feat/0.3.0-draft

Conversation

@rvolosatovs
Copy link
Copy Markdown
Contributor

@rvolosatovs rvolosatovs commented Jan 14, 2025

refs Ship WASIp3

Followed the example of wasi-http and wasi-clocks duplicating the package in a subdirectory

This vendors wasi-clocks from WebAssembly/wasi-clocks#77

  • In wasip3 return values of functions are pollable by guests, therefore remove abstractions for which there is no need anymore:
    • Replace start-X/finish-X function pairs by X
    • Remove would-block error code
    • Remove not-in-progress error code
  • Replace wasi:io/error.error usage by error-context
  • Replace wasi:io/streams.input-stream return values by stream<u8> in return position
  • Replace wasi:io/streams.output-stream return values by stream<u8> in parameter position - Guests should be able to rely on stream.new to construct streams

@rvolosatovs rvolosatovs force-pushed the feat/0.3.0-draft branch 2 times, most recently from 605a6b4 to 92f2c42 Compare January 14, 2025 11:44
@rvolosatovs rvolosatovs marked this pull request as ready for review January 14, 2025 11:44
Followed the example of `wasi-http` and `wasi-clocks` duplicating the
package in a subdirectory

- In wasip3 return values of functions are pollable by guests,
  therefore remove abstractions for which there is no need anymore:
     - Replace `start-X`/`finish-X` function pairs by `X`
     - Remove `would-block` error code
     - Remove `not-in-progress` error code
- Replace `wasi:io/error.error` usage by `error-context`
- Replace `wasi:io/streams.input-stream` return values by `stream<u8>`
  in return position
- Replace `wasi:io/streams.output-stream` return values by `stream<u8>`
  in parameter position
     - Guests should be able to rely on `stream.new` to construct
       streams

Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net>
This seems to be better aligned with latest specification on error context

https://github.com/WebAssembly/component-model/blob/cbdd15d9033446558571824af52a78022aaa3f58/design/mvp/Explainer.md#error-context-type

> A consequence of this, however, is that components *must not* depend on the
> contents of `error-context` values for behavioral correctness. In particular,
> case analysis of the contents of an `error-context` should not determine
> *error recovery*; explicit `result` or `variant` types must be used in the
> function return type instead (e.g.,
> `(func (result (tuple (stream u8) (future $my-error)))`).

Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net>
@rvolosatovs
Copy link
Copy Markdown
Contributor Author

After reading the error-context spec a bit more, it seems these are not meant to be introspected, therefore I added 8cc04c8

https://github.com/WebAssembly/component-model/blob/cbdd15d9033446558571824af52a78022aaa3f58/design/mvp/Explainer.md#error-context-type

A consequence of this, however, is that components must not depend on the
contents of error-context values for behavioral correctness. In particular,
case analysis of the contents of an error-context should not determine
error recovery; explicit result or variant types must be used in the
function return type instead (e.g.,
(func (result (tuple (stream u8) (future $my-error)))).

@lukewagner perhaps you could confirm that the changes in that commit are moving in the direction you'd expect?

WebAssembly/wasi-filesystem#164 (comment)

Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net>
@lukewagner
Copy link
Copy Markdown
Member

Yes, you're right about the direction; thanks for asking! Indeed, error-context is a value type (not a resource type) and so borrow<error-context> shouldn't even validate.

I'm not that familiar with wasi-sockets, but I wonder if we could simplify connect a bit so that we didn't have one function returning such a complex type. Could it look a bit more like:

resource tcp-socket {
  connect:func(n: borrow<network>, remote: ip-socket-address) -> result<tcp-connection, error-code>;
}
resource tcp-connection {
  write: func(tx: stream<u8>) -> result<option<error-code>>;
  read: func() -> result<tuple<stream<u8>, future<option<error-code>>>>;
}

(where read and write return fail if called while a preceding read/write is active)? This is roughly analogous to what we do in wasi-http for consuming bodies.

To wit, once we add stream<T,U> (not in 0.3.0, but in some 0.3.x follow-up), tcp-connection.read could be simplified to:

  read: func() -> result<stream<u8, option<error-code>>

cc @dicej for any other thoughts

rvolosatovs and others added 19 commits January 15, 2025 12:12
Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net>
…ymore, `listen` is free to do an implicit bind again. Just like POSIX.
… already covers all its use-cases. Was an oversight in v0.2
…ymore, `stream` is free to do an implicit bind again. Just like POSIX.
Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net>
Co-authored-by: Roman Volosatovs <rvolosatovs@users.noreply.github.com>
@badeend
Copy link
Copy Markdown
Member

badeend commented Jan 16, 2025

The suggestion of @rvolosatovs seems the most natural to me:

receive: func() -> tuple<stream<u8>, future<result<_, error-code>>>;

especially since that may be shortened even further to:

receive: func() -> stream<u8, error-code>;

depending on the progress of error-contexts

@rvolosatovs
Copy link
Copy Markdown
Contributor Author

Thanks @badeend, your changes look good to me, just left one comment.

Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net>
rvolosatovs added a commit to rvolosatovs/wasi-filesystem that referenced this pull request Jan 17, 2025
This ensures that e.g.:

```
wit-bindgen markdown wit-0.3.0-draft -w imports --html-in-md
```

works with wit-bindgen 0.37

refs:
WebAssembly/wasi-sockets@3abda6e

refs:
WebAssembly/wasi-sockets#111 (comment)

Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net>
badeend and others added 7 commits January 17, 2025 21:19
Co-authored-by: Roman Volosatovs <rvolosatovs@users.noreply.github.com>
…isten`, and provide guidance on how implementations may handle them.
…hen they're done, whereas UDP packets should be able to fail/succeed independently without affecting the transmission of other packets.

Without the stream parameter and return value, the `transfer` method is beginning to look an afwul lot like `connect` again, so we might as well call it that.
…tion of ComponentModel-level subtyping of value types, so that we could add additional fields (e.g. TTL, TOS, etc.) without breaking backwards-compatibility. AFAIK, that idea has been put on hold indefinitely, so we might as well make the 0.3.0 interface as simple as possible
@badeend
Copy link
Copy Markdown
Member

badeend commented Jan 19, 2025

Hi,

  • I've reverted the usage of streams on UDP sockets. streams are only able to fail once and then they're done, whereas UDP packets should be able to fail/succeed independently without affecting the transmission of other packets on the socket. Now, send & receive are regular methods as they were back in the day. Without the stream parameter and the stream return value, the transfer method is beginning to look an afwul lot like connect again, so we might as well call it that again.
  • I've removed the tcp-connection type and moved send & receive into tcp-socket. This simplifies the signatures of connect/listen and the general API design even further. This is at the expense of a bit of typestate, though at this point I've basically given up the hope this will ever be a pretty interface like that. Given the amount of existing invalid-state checks that already exist, I think it's more consistent to do these two final methods via runtime checks as well.
  • Removed outer result from tcp-socket::receive, as discussed above and already applied in wasi-filesystem.
  • Removed inbound/outbound-datagram records. They were added in anticipation of ComponentModel-level subtyping of value types, so that we could add additional fields (e.g. TTL, TOS, etc.) without breaking backwards-compatibility. AFAIK, that idea has been put on hold indefinitely, so we might as well make the 0.3.0 interface as simple as possible.
  • And some further documentation updates.

As before, let me know what you think!

@rvolosatovs
Copy link
Copy Markdown
Contributor Author

I think this looks good. Especially, since this is still meant to be a draft, I'd prefer validating this API by implementing it in a runtime (Wasmtime) and a component.

@badeend
Copy link
Copy Markdown
Member

badeend commented Jan 21, 2025

Alright, I think this is already more than good enough for the first draft, so I'm going to merge it now.

@badeend badeend merged commit c754b33 into WebAssembly:main Jan 21, 2025
sunfishcode pushed a commit to WebAssembly/wasi-filesystem that referenced this pull request Feb 4, 2025
* feat: add `wasi-0.3.0` draft

Followed the example of `wasi-http` and `wasi-clocks` duplicating the
package in a subdirectory

- Remove `would-block` error code
- Replace `wasi:io/error.error` usage by `error-context`
- Replace `wasi:io/streams.input-stream` return values by `stream<u8>`
  in return position
- Replace `wasi:io/streams.output-stream` return values by `stream<u8>`
  in parameter position
     - Guests should be able to rely on `stream.new` to construct
       streams
- Merge `read{,via-stream}` into a singular `read`. Both functions take
  an offset as a parameter and since they now return `stream<u8>`,
  callers can limit the amount of bytes read by using the `stream<u8>`
  directly, therefore functionality of both is identical
- Merge `write{,via-stream}` into a singular `write`. Both functions take
  an offset and `stream<u8>` as a parameter.

It is assumed that `error-context` returned by writes to the stream and
reads from the stream are sufficient for error handling.

Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net>

* refactor: avoid introspecting `error-context`

This seems to be better aligned with latest specification on error context

https://github.com/WebAssembly/component-model/blob/cbdd15d9033446558571824af52a78022aaa3f58/design/mvp/Explainer.md#error-context-type

> A consequence of this, however, is that components *must not* depend on the
> contents of `error-context` values for behavioral correctness. In particular,
> case analysis of the contents of an `error-context` should not determine
> *error recovery*; explicit `result` or `variant` types must be used in the
> function return type instead (e.g.,
> `(func (result (tuple (stream u8) (future $my-error)))`).

Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net>

* chore: bump `@since` to `0.3.0`

#164 (comment)

Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net>

* refactor(0.3): simplify error handling

Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net>

* refactor(0.3): asyncify `read-directory`

Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net>

* feat: update wit-deps to 0.5.0

Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net>

* drop `-draft` version suffix

This ensures that e.g.:

```
wit-bindgen markdown wit-0.3.0-draft -w imports --html-in-md
```

works with wit-bindgen 0.37

refs:
WebAssembly/wasi-sockets@3abda6e

refs:
WebAssembly/wasi-sockets#111 (comment)

Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net>

---------

Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net>
yoshuawuyts pushed a commit to yoshuawuyts/WASI that referenced this pull request Nov 25, 2025
* feat: add `wasi-0.3.0` draft

Followed the example of `wasi-http` and `wasi-clocks` duplicating the
package in a subdirectory

- Remove `would-block` error code
- Replace `wasi:io/error.error` usage by `error-context`
- Replace `wasi:io/streams.input-stream` return values by `stream<u8>`
  in return position
- Replace `wasi:io/streams.output-stream` return values by `stream<u8>`
  in parameter position
     - Guests should be able to rely on `stream.new` to construct
       streams
- Merge `read{,via-stream}` into a singular `read`. Both functions take
  an offset as a parameter and since they now return `stream<u8>`,
  callers can limit the amount of bytes read by using the `stream<u8>`
  directly, therefore functionality of both is identical
- Merge `write{,via-stream}` into a singular `write`. Both functions take
  an offset and `stream<u8>` as a parameter.

It is assumed that `error-context` returned by writes to the stream and
reads from the stream are sufficient for error handling.

Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net>

* refactor: avoid introspecting `error-context`

This seems to be better aligned with latest specification on error context

https://github.com/WebAssembly/component-model/blob/cbdd15d9033446558571824af52a78022aaa3f58/design/mvp/Explainer.md#error-context-type

> A consequence of this, however, is that components *must not* depend on the
> contents of `error-context` values for behavioral correctness. In particular,
> case analysis of the contents of an `error-context` should not determine
> *error recovery*; explicit `result` or `variant` types must be used in the
> function return type instead (e.g.,
> `(func (result (tuple (stream u8) (future $my-error)))`).

Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net>

* chore: bump `@since` to `0.3.0`

WebAssembly/wasi-filesystem#164 (comment)

Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net>

* refactor(0.3): simplify error handling

Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net>

* refactor(0.3): asyncify `read-directory`

Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net>

* feat: update wit-deps to 0.5.0

Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net>

* drop `-draft` version suffix

This ensures that e.g.:

```
wit-bindgen markdown wit-0.3.0-draft -w imports --html-in-md
```

works with wit-bindgen 0.37

refs:
WebAssembly/wasi-sockets@3abda6e

refs:
WebAssembly/wasi-sockets#111 (comment)

Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net>

---------

Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants