Skip to content
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

async Read/Write: can we use async read instead of non_blocking_read? #10

Open
nrc opened this issue Jun 29, 2022 · 6 comments
Open

async Read/Write: can we use async read instead of non_blocking_read? #10

nrc opened this issue Jun 29, 2022 · 6 comments
Labels
A-stdlib Area: a standard library for async Rust question Further information is requested

Comments

@nrc
Copy link
Owner

nrc commented Jun 29, 2022

Because returning WouldBlock is pretty much like returning Pending, except that it gets processed by the user in the ready loop rather than an executor, but that seems not important. If it works, this would make the Read and Write traits much simpler

Credit for the idea to @joshtriplett

@nrc nrc added question Further information is requested A-stdlib Area: a standard library for async Rust labels Jun 29, 2022
@nrc
Copy link
Owner Author

nrc commented Jun 29, 2022

Some thoughts from initial investigations:

The key difference between non_blocking_read and async read is about intentions and invariants: if non_blocking_read would block then that is probably due to the data already being consumed, so the caller should go back to waiting for ready. OTOH, async read might be not ready for many reasons, and the expected behaviour is for the caller to continue to poll the returned future.

If we only have async read, then there is the problem that inside the function body, we don't know whether we have been called from a poll loop (e.g., awaiting the method) or an explicit ready loop. That means we cannot write an optimal implementation because there must be a ready loop inside the method (which would cause problems if called from an external ready loop).

Implementers must also only use a single await and not return pending for any reason other than to indicate that the call would block. If they don't do this, then calling from a ready loop will not work because on a pending result, the caller will drop the future and await ready again. I think that means that code in ready must be duplicated in async read.

Another issue is that although this simplifies the API of Read and Write, it doesn't make things very easy for intermediate implementers. They must still consider ready and cannot write async Read as a simple wrapper function.

@NobodyXu
Copy link

What about completion based async io like io-uring?

In io-uring setting, you can submit a read I/O to network or filesystem in a truly async manner and simply wait for the entry to appear in cqe, and you don't need any poll/epoll or other ready call.

@nrc
Copy link
Owner Author

nrc commented Jun 29, 2022

Completion based IO is likely to use BufRead or OwnedRead or similar, rather than these functions

@Noah-Kennedy
Copy link

I'm in agreement with @nrc here.

@SabrinaJewson
Copy link

If we were to add a Leak auto trait, then completion-based I/O systems could use async fn read as well as a BufRead interface (for io_uring’s registered buffer mode). I think that’s the optimal solution since it has parallels with synchronous code (enabling keyword genericity with async) and allows completion and readiness-based systems to operate under the same API (so runtimes can transparently choose between the two at runtime). Therefore, by having the async I/O traits mirror their synchronous counterparts, although today it won’t benefit completion-based systems, it might be able to in future and I think that’s a very important feature to have.

@Noah-Kennedy
Copy link

With uring, it's interesting because you actually have efficient readiness-based IO via IORING_OP_POLL, however you just have more efficient APIs that are completion based which you generally want to use instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-stdlib Area: a standard library for async Rust question Further information is requested
Projects
None yet
Development

No branches or pull requests

4 participants