[rust-dev] Multiplexing I/O the Erlang way: an "ioserver"
bascule at gmail.com
Wed Jan 29 01:40:27 PST 2014
libnative (fast, low-latency native I/O) and libgreen (libuv backed and
great for large numbers of infrequent/idle messengers) are both awesome and
provide some great options for network server I/O, particularly since you
can mix-and-match them.
However there's a seemingly unsolved problem in Rust: multiplexing I/O
operations with channels. I think this can be fixed in a purely additive
manner (i.e everything else that exists today is great!) with a new feature
borrowed from Erlang: the ioserver (noting that Erlang also implements
libgreen-style synchronous I/O in addition to ioserver)
Ignoring Erlang for a second, the naive solution to the I/O + channel
multiplexing is magic select API that can handle both. In my experience
(i.e. I wrote and support this approach in a system some people actually
use) the backend implementation, especially across POSIX and Windows, ends
up quite ugly.
There's a better option though... if you want to multiplex IO with channel
messages, turn everything into channel messages in one place: the "ioserver"
Solution: Centralize I/O event loops into a separate thread (pool if
necessary, probably not). Erlang and 0MQ work this way. Erlang implements
an API called a "port" to talk to the ioserver. In Rust perhaps you could
have a type that implements the same trait as channels?
The ioserver becomes the central place to optimize the nitty gritty of
taking I/O requests from the rest of the program and multiplexing them with
other (i.e channel) events in the system. The basic formula is:
- Have the ioserver block for events using libuv or what have you, and have
an OS-specific I/O handle (i.e. a pipe) to unblock the selector in the
event of in-process communication
- Use lock-free mechanisms so if the selector isn't stuck in a system call
we can use more efficient coordination of registering and unregistering I/O
(Note: libuv is an I/O completions library and not a selector library so
the proposed solution is admittedly a bit handwavey)
Mixing a pipe-based wakeup mechanism with lock-free operations to eliminate
unnecessary system calls has been used somewhat successfully in the Netty
I/O library for the JVM.
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Rust-dev