Crate timer_deque_rs

Crate timer_deque_rs 

Source
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:

§Features

  • bsd_use_timerfd - use timerfd instead of kqueue
  • bsd_use_poll - use poll instread of kqueue

§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.

Macros§

map_portable_err
map_timer_err
portable_err
timer_err