WebAssembly / wasi-io

I/O Types proposal for WASI
Other
144 stars 20 forks source link

New backpressure and flushing scheme for output-stream #45

Closed pchickey closed 1 year ago

pchickey commented 1 year ago

output-stream's backpressure design has been changed to take into account that any write call with a list<byte> argument is going to consume the resources of a component implementation, by copying those bytes into the component's linear memory.

Therefore, prior to a call to write, the user of this interface must first call check-write to learn how many bytes the implementation will accept in a call to write. The check will return 0 bytes when calls to write are not accepted, as well as reporting with an error if the prior operation failed or the stream has closed. The subscribe-to-output-stream pollable, which has always reported write readiness, will now become ready whenever check-write will return a value other than ok(0).

Flushing is a way to request & observe the completion of a write. Since the write itself is non-blocking, it may need to buffer writes and perform work in the background (in a component implementation, this would be during a call to poll-oneoff). The explicit flush call allows the user to wait for a write (or sequence of writes) to produce an error, or guarantee that it succeeded. After requesting a flush, check-write return ok(0) until the flush is complete, or an error has occured. Accordingly, the subscribe-to-output-stream pollable becomes ready when the flush is complete.

Replacing blocking-write is blocking-write-and-flush, because the combination of write and flush is what we have found many implementations (e.g. an implementation of posix write(2)) require. Rather than participate in the new backpressure scheme, blocking-write-and-flush always accepts a write of up to 4096 bytes at a time, a threshold that was picked to large enough to be useful for common cases such as stdio debugging prints, but small enough to not be a burden for the implementation.

blocking-flush is also provided as a convenience function.

Wasmtime implementation: https://github.com/bytecodealliance/wasmtime/pull/6877

sunfishcode commented 1 year ago

Looks good! I expect we'll have some details to look into, but I think it makes sense to merge this now and iterate from here.