4 ms·
I've found in my own use of rust I want async/nonblocking for two things. 1. Be able to timeout a read of a socket 2. Be able to select over multiple sockets,
by moggers 5y ago
I've found in my own use of rust I want async/nonblocking for two things.
1. Be able to timeout a read of a socket
2. Be able to select over multiple sockets, and read whichever is ready first
Usually a combination of both.
epoll/io_uring(I guess? I only ever did research on epoll) seem like the solution being handed to me on a silver platter, however my understanding is if you want to use either of those you're meant to use async in rust, and that while there are some libraries which provide interfaces for this kind of behavior outside of async, they're usually very ad-hoc and that the community is just very laser focused on async as a language construct.
What I don't understand is why does Rust consider it necessary to introduce async, futures, runtimes, an executor, async versions of TcpListeners, Files, etc for this?
Why can't I just have a function in the standard library that takes a slice of std::net::TcpListeners, a timeout, blocks, and then gives me whichever is ready to read, when its ready to read, or nothing if the timeout is reached? Its not like I was going to do anything else on that thread while I wait for a packet to be received, it can happily be parked.
Instead I have to select a runtime, and libraries compatible with the runtime, replace all the TcpListeners from the standard library I'm using with tokio TcpListeners or whatever, deal with API change, and now I have to deal with the "turtles all the way down" problem of async as well.
That's not even to get into the whole nightmare that a lot of really sick libraries which I want to use in a blocking nature, are now only providing async APIs, which means its "async or the highway". I am very much not happy about this situation and I don't know what I can do about it. It seems the only response I ever get is "just use it, its easy" but that is not at all convincing me. I don't want to use it!
- mleonhard 5y agoIf you need to handle <100,000 sockets, you will probably be fine with a thread per socket. Call set_read_timeout to implement the deadline. Run load tests and adjust the socket limit. Async lets one process handle millions of sockets. If you want to handle millions of sockets with threads, you can use `mio` [0]. Mio's API has footguns that can cause UB. If your wire protocol is complicated, you may find yourself implementing something like async, but worse. [0] https://crates.io/crates/mio https://crates.io/crates/mio
- GolDDranks 5y agoYou can absolutely do readiness-based IO. Either call the system-specific APIs or use the MIO library, which is a low-level platform abstraction for that: https://github.com/tokio-rs/mio https://github.com/tokio-rs/mio