On Mon, Jul 6, 2020 at 10:54 AM Vitali Lovich <[email protected]> wrote:

> I think a potential middle ground for this might be to have the stream
> give you the fd and a fulfiller. Any I/O operations on the stream then are
> blocked from executing until after the promise to return the FD is
> fulfilled.
>

That's an interesting idea. Or rather, I'd have it return a "BorrowedFd"
object which gives you access to the FD, and whose destructor unblocks the
stream.

That said, it is already the case today that concurrent operations on a
stream in the same direction (e.g. calling write() again when a previous
write() hasn't finished) is undefined behavior. By the same logic as your
argument, we should instead have the second write() block until the first
one finishes. And I would indeed agree that, in theory, that is better
behavior. But, I don't like the amount of complexity that creates for the
stream implementation. If AsyncStreamFd were the only implementation of
AsyncIoStream, then I'd say, fine, we can handle it. But lots of other
places, including apps, implement AsyncIoStream in various ways, and it
would be a big burden for all of them to handle concurrent operations
gracefully. Meanwhile, this behavior would be of very little benefit to the
vast majority of callers; in practice, streams naturally tend to be
accessed sequentially.

So, I prefer to keep the burden on the caller to make sure they don't issue
concurrent operations. And it seems to me that this policy extends
naturally to borrowing the FD.


> I don't think the WebServer would need an FdObserver because you could
> return the FD in blocking mode & the user could dispatch the I/O to a
> background thread & get back onto the executor to fulfill the promise once
> complete. Not like sendfile and non-blocking interact all that well.
>

I don't agree here. I don't think most use cases would call for spawning
background threads to do blocking I/O. splice(), for example, interacts
with non-blocking IO quite nicely. (And whether or not you consider
sendfile() to play nice with non-blocking IO kind of gets into a
philosophical debate of whether the disk should properly be treated as a
remote device vs. "L5 memory". Not everyone agrees on this topic.)

Also, switching the FD to blocking mode would imply that you *cannot* use
this method while having any async reads or writes in-flight, even if you
don't plan to issue any conflicting reads or writes. E.g. what if you just
want the FD to perform an ioctl() on it? Or you want to do manual writes
but use the regular KJ machinery for reads?

-Kenton

>

-- 
You received this message because you are subscribed to the Google Groups 
"Cap'n Proto" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/capnproto/CAJouXQk3n0BsUGQG_j5Fn2GEX2uT-uYNnAsyOcyBTLs3T8XhMA%40mail.gmail.com.

Reply via email to