I/O-free time library written in Rust, based on io-socket.
This library allows you to manage timers using an I/O-agnostic approach, based on 3 concepts:
A coroutine is an I/O-free, resumable and composable state machine that emits I/O requests. A coroutine is considered terminated when it does not emit I/O requests anymore.
See available coroutines at ./src/coroutines.
A runtime contains all the I/O logic, and is responsible for processing I/O requests emitted by coroutines.
See available runtimes at ./src/runtimes.
The loop is the glue between coroutines and runtimes. It makes the coroutine progress while allowing the runtime to process I/O.
timer— enables theTimerRequestSendandTimerRequestHandlecoroutines; addsio-socketandserde_jsondependenciesstd— enables the standard blocking runtime (runtimes::std)
TimeNow, TimeSleep, and TimeSleepUntil are always available as the core of the crate.
Default: timer + std.
use std::net::TcpStream;
use io_socket::runtimes::std::handle as socket_handle;
use io_time::coroutines::client::{TimerRequestSend, TimerRequestSendResult};
let mut stream = TcpStream::connect("localhost:1234").unwrap();
let mut arg = None;
let mut client = TimerRequestSend::start();
loop {
match client.resume(arg.take()) {
TimerRequestSendResult::Ok { .. } => break,
TimerRequestSendResult::Io { input } => arg = Some(socket_handle(&mut stream, input).unwrap()),
TimerRequestSendResult::Err { err } => panic!("{err}"),
}
}use std::os::unix::net::UnixListener;
use io_socket::runtimes::std::handle as socket_handle;
use io_time::{
coroutines::server::{TimerRequestHandle, TimerRequestHandleArg, TimerRequestHandleResult},
runtimes::std::handle as time_handle,
timer::{Timer, TimerConfig},
};
let mut timer = Timer::new(TimerConfig { /* … */ });
let listener = UnixListener::bind("/tmp/timer.sock").unwrap();
let (mut stream, _) = listener.accept().unwrap();
let mut server = TimerRequestHandle::new();
let mut arg: Option<TimerRequestHandleArg> = None;
loop {
match server.resume(&mut timer, arg.take()) {
TimerRequestHandleResult::Ok { events } => { /* handle events */ break }
TimerRequestHandleResult::Io { input } => {
arg = Some(TimerRequestHandleArg::Socket(socket_handle(&mut stream, input).unwrap()))
}
TimerRequestHandleResult::TimeIo { input } => {
arg = Some(TimerRequestHandleArg::Time(time_handle(input).unwrap()))
}
TimerRequestHandleResult::Err { err } => panic!("{err}"),
}
}See projects built on top of this library:
- comodoro: CLI to manage timers
Special thanks to the NLnet foundation and the European Commission that helped the project to receive financial support from various programs:
- NGI Assure in 2022
- NGI Zero Entrust in 2023
- NGI Zero Core in 2024 (still ongoing)
If you appreciate the project, feel free to donate using one of the following providers:
