Add optional close/shutdown message to AsyncWriteStream #9680
+61
−2
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
This proposal adds an optional
Receiver<()>
field toAsyncWriteStream
. When signalled, this gracefully closes the underlyingAsyncWrite
.Context
This emerged from trying to implement wasi-blobstore. I was passing the read end of a stream to a back-end provider, and the write end to the guest. I was using
wasmtime_wasi
to store the write end in a resource table as aHostOutputStream
because I didn't want to write a stream host interface myself!The API specifies that the guest calls a "finish" method (on a separate
outgoing-value
resource) to indicate that it has finished writing to the stream. However, because I was usingAsyncWriteStream
andwasmtime_wasi::HostOutputStream
, my host didn't have access to the underlying AsyncWrite'sshutdown
function to EOF the stream. So the reader at the back end would continue waiting for input.My first plan was to add a
shutdown
function toAsyncWriteStream
, but I couldn't downcastHostOutputStream
toAsyncWriteStream
, so that didn't work. So what I ended up with was:AsyncWrite
.outgoing-value
resource) hold the sender end of the channel.outgoing-value::finish
, send a message via the sender.This seemed to work, although it's not been extensively tested.
As an interface, it's awkward, because for most operations you interact with
AsyncWriteStream/HostOutputStream
via methods, but for this one special case you interact with it via a sync channel. However, I don't see a way round that without adding a shutdown or close method to the WASIoutput-stream
resource. It's possible that WASI intends that shutdown be done by dropping theoutput-stream
resource, but in my testing this seemed to result in an abort rather than an EOF.So after talking to @alexcrichton I'm putting this up for discussion and in the hope that WASI folks can come up with a better solution. Please let me know if folks need clarifications around the problem I was trying to solve or the constraints that led me in this direction!