tetratelabs / wazero

wazero: the zero dependency WebAssembly runtime for Go developers
https://wazero.io
Apache License 2.0
4.81k stars 250 forks source link

support non-blocking files #1500

Open codefromthecrypt opened 1 year ago

codefromthecrypt commented 1 year ago

Is your feature request related to a problem? Please describe.

Currently, we support non-blocking stdio and sockets, but not files. This leads to an awkward and unnecessary skip in go's tests.

Describe the solution you'd like

Go supports non-blocking access and we support native access to files, so we should be able to implement this. If there are any caveats about windows, support can begin with a limited set of platforms.

Describe alternatives you've considered

continue to not do this

Additional context

our file type already has a SetNonblock setting, so that's a start. We also have a separate file implementation for raw os-backed files. So, we should be able to figure out why we aren't implementing non-blocking access for os files, then figure out how to implement it.

evacchi commented 1 year ago

a quick summary of what's required to make this works.

In theory, we can easily enable SetNonblock() for regular files, but effectively it would only work on *NIX. In fact, the syscall.SetNonblock() fun on Windows is a no-op.

Now, even if we did support that only on *NIX, we should still fix poll_oneoff; because as much as it would still work without it (read() returns EAGAIN and you could just retry after a little), existing code may still assume that select works.

so:

now the good news about poll_oneoff is that there actually is a select() implementation that works on Windows ... the bad news it only works on sockets. Better than nothing.

So in short:

EDIT: on a second thought. Apparently regular files always return immediately from poll_oneoff. So technically our implementation is correct also on Windows 😅

Now I am tempted to take a look at sockets 🤔

codefromthecrypt commented 1 year ago

some trouble in HTTP land. I began troubleshooting with @chriso but I think we should all be able to enjoy a weekend and I don't think this will quickly resolve. https://github.com/tetratelabs/wazero/pull/1503

codefromthecrypt commented 1 year ago

so next step is to really look carefully at windows and sockets, and find some real-world wasm (very hard to find, like this and this) which can verify assumptions.

evacchi commented 1 year ago

as for PR #1502, this only enables non-blocking I/O for files on *NIX.

Interesting notes, really on regular files poll always returns OK, except that then read() may still return EAGAIN l https://www.remlab.net/op/nonblock.shtml. (In the tests we are using pipes). On Windows Pipes do exist but they require quite a bit of boilerplate to initialize, to the point there are literally go libraries that only do that https://github.com/gesellix/go-npipe https://github.com/natefinch/npipe

Summary for further work on Windows.

Long story short, it should be feasible to provide select, and thus poll_oneoff for sockets on Windows too, but it will require some rework of the current poll_oneoff impl, which is really ad-hoc for stdin :^)

codefromthecrypt commented 1 year ago

Thanks for the update. Really good info!

Aside: I think one thing we need before closing this also, is a gotip version of the zig non-blocking test, as it isn't intuitive how to set it up. the question came up on slack by @tegk.

evacchi commented 1 year ago

some further work in #1517 on unix. This should address most issues on this platform (with some love probably still needed for poll_oneoff), while work on Windows needs the most attention

chriso commented 1 year ago

Related: https://github.com/tetratelabs/wazero/issues/1538

evacchi commented 1 year ago

1570 improved support to pipes on Windows. I think that if we fix sockets (just use WinSock select) and we tie everything together in poll_oneoff, we are getting closer to resolving this!

shynome commented 3 months ago

hi, is there any api to set nonblock

this make me fall down again. :(