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

Getting raw IO Errors for read_message #254

Open
Kilobyte22 opened this issue Jan 12, 2022 · 3 comments
Open

Getting raw IO Errors for read_message #254

Kilobyte22 opened this issue Jan 12, 2022 · 3 comments

Comments

@Kilobyte22
Copy link

Kilobyte22 commented Jan 12, 2022

If an IO Error happens in the underlying Read, it is not possible to correctly identify what exactly happened (without hacks like parsing the error message). In particular, i have a socket that has a read timeout set. Once it expires, the linux kernel throws an EAGAIN ("Resource Temporarily unavailable"), which i would like to handle differently than other IO Errors.

Proposed solution: Store the underlying std::io::Error within the capnp::Error and implement std::error::Error::source for capnp::Error. It should be completely possible to do this in a backwards compatible way. If there is interest i can write a pull request for that, but I'd like some feedback on this first.

the other functions in the serialize module have the same problem, but read_message is the one thats of particular interest to me right now. However, when implementing this, it would make sense to cover all of them at the same time.

@dwrensha
Copy link
Member

In order to support no_alloc environments (#221), I'd actually like to move to a world where capnp::Error does not have a String but instead is an enum with a bunch of error variants. One of the variants could be "io error" and could keep the underlying error code.

How do you intend to handle EAGAIN? If you're working with non-blocking I/O, is there a reason that the capnp-futures crate does not work for you?

@Kilobyte22
Copy link
Author

I want to keep my binary as small as possible (as it is intended to be running in an embedded environment). I therefore want to keep dependencies as few as possible and all async runtimes known to me are pretty large.

EAGAIN would be handled by simply retrying after a couple of background checks (like a connection timeout, or the wish to close the connection)

@dwrensha
Copy link
Member

I agree that retrying after EAGAIN could work if it's the initial read() call that returns EAGAIN. However, capnp::serialize::read_message() generally makes many read() calls. What if some of them success and then one returns EAGAIN? The intermediate state will be gone, and unless you have a way to rewind the Read, retrying won't work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants