Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wasi-io: Missing would-block in stream-error (Returning 0 from TcpReader::read) #9667

Open
Heap-Hop opened this issue Nov 23, 2024 · 3 comments

Comments

@Heap-Hop
Copy link

Heap-Hop commented Nov 23, 2024

// Failing with `EWOULDBLOCK` is how we differentiate between a closed channel and no
// data to read right now.
Err(e) if e.kind() == std::io::ErrorKind::WouldBlock => 0,

Returning 0 for std::io::ErrorKind::WouldBlock causes downstream to interpret it as a closed stream, see:
yoshuawuyts/wstd#25 (comment).
https://github.com/yoshuawuyts/wstd/blob/5ce367add5e7bcb569b6487453cb9ba94468dc99/src/io/copy.rs#L12

This is also found in:

// The input stream should immediately signal StreamError::Closed.
// Notably, it should _not_ return an empty list (the wasi-io equivalent of EWOULDBLOCK)
// See: https://github.com/bytecodealliance/wasmtime/pull/8968
assert!(matches!(client.input.read(10), Err(StreamError::Closed)));

Given that the wit files already include many would-block errors, would it make sense to extend stream-error to include a would-block?

@pchickey
Copy link
Contributor

pchickey commented Nov 24, 2024

WASI streams operations are nonblocking, unless they have blocking_ in their name, so read should always return an empty list instead of blocking. The blocking_ functions are equivalent to waiting for readiness on the stream's pollable, and then calling the nonblocking variant.

This is a significant departure from POSIX, which uses the file's mode to make the read and write syscalls blocking or nonblocking. So, while it makes sense for POSIX to use an error to indicate when a nonblocking socket would block, it doesn't make sense for WASI to follow that same convention.

@bjorn3
Copy link
Contributor

bjorn3 commented Nov 24, 2024

How can you distinguish in WASI between an EOF stream (no data will be returned in the future because the connection was closed or the end of the file is reached) and a stream where you have to wait until the stream is ready before you can read more data? The distinction is very important for std::io::copy/tokio::io::copy which needs to continue reading until EOF and only returns when EOF is reached.

@pchickey
Copy link
Contributor

pchickey commented Nov 24, 2024

When the stream is EOF, it returns Err(StreamError::Closed) as seen in the above snippet line 21. Maybe this isn't so much an "Error" as the "Err" constructor indicates, but the alternative was returning a custom enum there of Ok/Closed/Error, which we rejected on fairly arbitrary stylistic grounds.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants