Expand description
§timer-deque-rs
§A crate which combines a timer with the different deque types.
§Timer dequeue
A deque which uses timer to deque objects.
§Two deque opeartion modes:
-
OrderdTimerDequeOnce - after a timeout an item is removed from the queue.
-
OrderdTimerDequePeriodic - after the timeout an item’s timeout is extended and item is returned back to queue. It should be manually removed.
§Features
§Below is related to BSD systems
bsd_use_timerfd
- usetimerfd
instead ofkqueue
bsd_use_poll
- usepoll
instread ofkqueue
§Three deque types:
TimerDequeueConsumer consumes the item and places it on the queue.
let mut time_list =
OrderedTimerDeque
::<TimerDequeueConsumer<TestItem, OrderdTimerDequeOnce>>
::new("test_label".into(), 4, false).unwrap();
or
let mut time_list =
OrderedTimerDeque
::<TimerDequeueConsumer<TestItem, OrderdTimerDequePeriodic>>
::new("test_label".into(), 4, false).unwrap();
TimerDequeueSignalTicket sends signal as specified in the callback(non-blocking) for every added item.
let mut time_list =
OrderedTimerDeque
::<TimerDequeueSignalTicket<TestSigStruct, OrderdTimerDequeOnce>>
::new("test_label".into(), 4, false).unwrap();
or
let mut time_list =
OrderedTimerDeque
::<TimerDequeueSignalTicket<TestSigStruct, OrderdTimerDequePeriodic>>
::new("test_label".into(), 4, false).unwrap();
TimerDequeueTicketIssuer issues a ticket which can be dropped (deallocated), so timer would ignore item.
let mut time_list =
OrderedTimerDeque
::<TimerDequeueTicketIssuer<OrderdTimerDequeOnce>>
::new("test_label".into(), 4, false).unwrap();
or
let mut time_list =
OrderedTimerDeque
::<TimerDequeueTicketIssuer<OrderdTimerDequePeriodic>>
::new("test_label".into(), 4, false).unwrap();
§Timers polling
For the sync
a Epoll
for Linux and Kqueue
for BSD are used. Both are
wrapped into TimerPoll.
let ev_watch = TimerPoll::new().unwrap();
let mut time_list =
OrderedTimerDeque
::<TimerDequeueConsumer<Arc<TestItem>, OrderdTimerDequeOnce>>
::new("test_label".into(), 4, false).unwrap();
// add timer to event
ev_watch.add(&time_list).unwrap();
In case if monitored timer, for example, time_list
from above exmaple would be dropped intentionally or
by acident, it will be automatically removed from the poll queue. If, for any reason the ev_watch
becomes
invalid i.e dropped, all added instances will be unbinded from this TimerPoll instance and can be reused.
Alternativly, OrderedTimerDeque provides blocking/nonblocking function
wait_for_event
which is less efficient.
For the async
a Future is implemented. Polling future
is not too
efficient (the same situation with wait_for_event
).
let mut time_list =
OrderedTimerDeque
::<TimerDequeueConsumer<Arc<TestItem>, OrderdTimerDequeOnce>>
::new("test_label_async".into(), 4, false)
.unwrap();
let res = time_list.poll().await.unwrap();
// ...
// read timeout items
time_list.timeout_event_handler(res, &mut timeout_items).unwrap();
For more efficient polling
of Timer for event, use async crates like
smol
, tokio
or other. In case of tokio
an AsyncFd can be used.
let time_list =
OrderedTimerDeque
::<TimerDequeueSignalTicket<TestStruct>, OrderdTimerDequeOnce>
::new("test_label".into(), 4, false)
.unwrap();
let mut async_time_list = AsyncFd::new(time_list).unwrap();
// poll the timer until it becomes ready
let mut read_guard =
async_time_list.ready_mut(Interest::READABLE).await.unwrap();
// clear ready otherwise it will return WOULDBLOCK
read_guard.clear_ready();
// read events
let res = read_guard.get_inner().wait_for_event().unwrap();
§Timer
A timer can be used directly.
// timer init as blocking
let timer =
TimerFd::new(Cow::Borrowed("test"), TimerType::CLOCK_REALTIME, TimerFlags::empty()).unwrap();
// setting the timout and timer mode
let abs_time = AbsoluteTime::now().add_sec(3);
// the flags will be set automatically
let exp_time =
TimerExpMode::<AbsoluteTime>::new_oneshot(abs_time);
// setting timer
let res =
timer.set_time(exp_time);
// read timer
let ovf = timer.read().unwrap().unwrap();
The above is not too efficient because in case of nonblocking
, it will return none immidiatly and
in case of blocking
it would block thread.
A Epoll
, Select
, KQueue
can be used to poll timer more efficient. Or, for example, AsyncFd
from
tokio
can be used too.
§Task spawn and executer
A parallel task execution based on the task timeout.
#[derive(Debug)]
struct TaskStruct1
{
a1: u64,
s: Sender<u64>,
}
impl TaskStruct1
{
fn new(a1: u64, s: Sender<u64>) -> Self
{
return Self{ a1: a1, s };
}
}
impl PeriodicTask for TaskStruct1
{
fn exec(&mut self) -> PeriodicTaskResult
{
println!("taskstruct1 val: {}", self.a1);
let _ = self.s.send(self.a1);
return PeriodicTaskResult::Ok;
}
}
// ...
let s = SyncPeriodicTasks::new(2.try_into().unwrap()).unwrap();
// ...
let task1 = TaskStruct1::new(0, send.clone());
let task1_ptt =
PeriodicTaskTime::interval(RelativeTime::new_time(1, 0));
let task5 = TaskStruct1::new(4, send.clone());
let task5_ptt =
PeriodicTaskTime::exact_time(AbsoluteTime::now() + RelativeTime::new_time(5, 0));
let task1_guard = s.add("task1", task1, task1_ptt).unwrap();
let task5_guard = s.add("task5", task5, task5_ptt).unwrap();
// ...
Re-exports§
pub extern crate bitflags;
pub extern crate chrono;
pub extern crate crossbeam_deque;
pub extern crate nix;
pub extern crate rand;
pub use deque_timeout::OrderedTimerDeque;
pub use deque_timeout::OrderdTimerDequeOnce;
pub use deque_timeout::OrderdTimerDequePeriodic;
pub use deque_timeout::timer_consumer::TimerDequeueConsumer;
pub use deque_timeout::timer_signal::TimerDequeueSignal;
pub use deque_timeout::timer_signal::TimerDequeueSignalTicket;
pub use deque_timeout::timer_tickets::TimerDequeueTicketIssuer;
pub use deque_timeout::timer_tickets::TimerDequeueTicket;
pub use timer_portable::TimerPoll;
pub use timer_portable::TimerReadRes;
pub use timer_portable::FdTimerCom;
pub use timer_portable::AbsoluteTime;
pub use timer_portable::RelativeTime;
pub use common::TimerDequeueId;
pub use periodic_task::PeriodicTask;
pub use periodic_task::PeriodicTaskResult;
pub use periodic_task::SyncPeriodicTasks;
pub use periodic_task::PeriodicTaskTime;
Modules§
- common
- Common things.
- deque_
timeout - A base implementation of the sorted timer timeout queue.
- error
- Crates error handling.
- periodic_
task - timer_
portable - All code which should be ported to the specific OS. Contains a system timer implementation and poll.