gaea 0.3.1

Low-level library to build event driven applications, supporting lightweight non-blocking I/O.
Documentation

A low-level library to build event driven applications. The core of the library is [poll], which polls multiple event sources for readiness events. Based on these readiness events the application will continue, e.g. by running a Future.

A number of readiness event sources are provided:

  • [OsQueue]: a readiness event queue backed by the OS (epoll or kqueue).
  • [Queue]: a single threaded, user space queue.
  • [Timers]: a single threaded, deadline based readiness queue.

Getting started

Using the crate starts by creating one or more [event::Source]s.

# use gaea::{OsQueue, Queue};
# fn main() -> std::io::Result<()> {
// `OsQueue` implements `event::Source` and is backed by epoll or kqueue.
let os_queue = OsQueue::new()?;
// `Queue` is a user space readiness event queue, which also implements
// `event::Source`.
let queue = Queue::new();
# drop((os_queue, queue));
# Ok(())
# }

As the name suggest event::Sources are the sources of readiness events, these can be polled for readiness events (we'll get back to this later). This crate provides three [OsQueue], [Queue] and [Timers]. But as event::Source is a trait it can be implemented outside of this crate.

Next an [event::Sink] is required, this used to store the readiness events from the event sources.

// `Vec`tor implements `event::Sink`.
let events = Vec::new();
# drop::<Vec<gaea::Event>>(events);

Just like event::Source, event::Sink is also a trait. When, for example, building some kind of runtime event::Source can be directly implemented on the scheduler type and instead of adding an [Event] to a collection it will schedule a process/Future/task to run. For convenience Vectors also implement event::Sink.

Both the event::Sources and event::Sink should only be created once and reused in each call to [poll]. After we created both we can start polling the event::Sources.

# use std::io;
# use std::time::Duration;
# use gaea::{poll, OsQueue, Queue};
# fn main() -> io::Result<()> {
# let mut os_queue = OsQueue::new()?;
# let mut queue = Queue::new();
# // Let poll return quickly.
# queue.add(gaea::Event::new(gaea::event::Id(0), gaea::Ready::READABLE));
# let mut events = Vec::new();
// Poll both `os_queue` and `queue` for readiness events, with a maximum
// timeout of 1 seconds. Here we use an `io::Error` as error, see `poll`
// docs for more information on handling errors from different event
// sources.
poll::<_, io::Error>(&mut [&mut os_queue, &mut queue], &mut events,
Some(Duration::from_secs(1)))?;
# Ok(())
# }

After the event::Sources are polled our event::Sink will be filled with readiness events, if there are any. These can be used to continue processing. Stick all the above in a loop and you've got yourself an event loop, congratulations!

use std::io;
use std::time::Duration;

use gaea::{poll, OsQueue, Queue};

# fn main() -> std::io::Result<()> {
// Create our `event::Source`s.
let mut os_queue = OsQueue::new()?;
let mut queue = Queue::new();
# // Let poll return quickly.
# queue.add(gaea::Event::new(gaea::event::Id(0), gaea::Ready::READABLE));

// And our `event::Sink`.
let mut events = Vec::new();

// TODO: add events and such here...

// Our event loop.
loop {
// Poll for readiness events.
poll::<_, io::Error>(&mut [&mut os_queue, &mut queue], &mut events,
Some(Duration::from_secs(1)))?;

// And process each event.
for event in events.drain(..) {
println!("Got event: id={}, readiness={:?}", event.id(),
event.readiness());
}
# return Ok(());
}
# }

Examples

More complete examples of how to use the crate can be found in the examples directory of the source code (on GitHub).