-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Remove special case for InputStream::File ? #9058
Comments
One major difficulty here is cancellation. All other |
Do you mean "difficulty" from a correctness point of view? Or from a Technical implementation / resource usage POV?
You mention "write", but this issue is specifically about input stream, i.e. reads only. Don't know if that changes things. Is there any harm in letting the read continue in the background? |
Sorry yeah my reading comprehension isn't great recently... But yes without true support for cancellation the guest can create an unbounded number of cancelled reads and the host has no way to handle that. That being said I don't fully remember the blockers for this. Things have gone back-and-forth on the design in wasmtime-wasi and requirements have additionally changed over time. If possible I agree it would be great to remove this enum, and if you're up for giving it a stab I'd recommend doing so. One possible solution to the cancelled read problem is (a) acknowledging that it will rarely come up and (b) placing a hard limit on the number of cancelled reads and refusing futher reads until the other ones are reaped. (or something like that). That may still run the risk though of not being able to bound cancelled reads across all guests (only within one guest). In any case I think it's reasonable to explore this space a bit, as the various blockers might be overcomable at this point. |
I guess there already is an upper bound in place: Tokio's
I'd be up for it. Just want to make sure I have the full picture before putting too much effort into it. |
We'd still have to worry about the unbounded-ness of the queued item to write as well. I don't think a thread pool per As I thought more about this though I think I remember the real reason why this is split. For normal streams we don't allow |
Okay, please don't go reaching for your pitchfork immediately, but: how about (a)synchronously joining the background task on drop (if any)? So instead of naughtily "blocking" the wasm guest on every read like we do today, only naughtily "block" them in the exceptional case that the stream is dropped mid-read/write. Definitely not the prettiest solution, I know, but still... :) Fwiw, if the guest uses wasi-libc, that exceptional case should occur basically never. |
I think that could theoretically work from a guest perspective but from a host perspective I don't think that would work since that would block a host thread, right? For async mode it should be guaranteed that no host thread ever blocks on I/O waiting for something else for a possibly long time. |
I was thinking more along the lines of adding an |
I don't have any additional context beyond what the discussion with Alex has covered, I'm definitely in favor of getting rid of the special case if you can find a design that works. We landed it because we just needed something that worked, even though the special case is kinda gross. |
I can't quite see how |
What I had in mind is this: cdd5f72 but this doesn't quite work. I assumed that the drop method was just a regular import that I could async'ify like any other by adding There appears to already be some infrastructure around async drops: wasmtime/crates/wasmtime/src/runtime/component/resources.rs Lines 978 to 984 in 2bf307a
but I don't know if/how this is useful. |
I've got something up and running: badeend@6d8c471 I added an additional |
Seems plausible yeah, thanks for writing that up! I'll do a review on Monday when I get back from travelling. |
All input streams are implemented using the
HostInputStream
trait. Except files. They get special treatment. This can be seen in the definition ofInputStream
:wasmtime/crates/wasi/src/stream.rs
Lines 165 to 168 in ba864e9
The special case was introduced to work around the fact that OS'es don't actually provide any true async APIs for files. A more detailed explanation can be read in the PR that introduced this setup: #6556
Currently,
FileInputStream::read
spawns the read syscall on a background thread and then immediatelyawait
s the newly created task. This is done to prevent blocking the executor, but from the WASM guest's point-of-view this doesn't provide any asynchronicity.My question: Instead of directly awaiting the background task, can we store the task handle in the
FileInputStream
instance and then use that handle to wait for readiness? Subsequent calls toFileInputStream::read
then inspect the result of the previously started background task (if any). And then letFileInputStream
implementHostInputStream
directly and get rid of the special case.From the surface this seems like an "obvious" solution, but the PR above also mentions:
which makes me suspect there's more to the story than meets the eye.
@pchickey, what do you think?
The text was updated successfully, but these errors were encountered: