Crate tokio_timer_futures2 [] [src]

Timer facilities for Tokio

The default timer implementation is a hashed timing wheel. This structure provides the best runtime characteristics for the majority of network application patterns as long as it is correctly configured. A hashed timing wheel's worst case is O(n) where n is the number of pending timeouts.

Most useful functions are on Timer.

Example

Here is a simple example of how to use the timer.

extern crate tokio_timer;
extern crate futures;

use tokio_timer::*;
use futures::*;
use std::time::*;

pub fn main() {
    // Create a new timer with default settings. While this is the easiest way
    // to get a timer, usually you will want to tune the config settings for
    // your usage patterns.
    let timer = Timer::default();

    // Set a timeout that expires in 500 milliseconds
    let sleep = timer.sleep(Duration::from_millis(500));

    // Use the `Future::wait` to block the current thread until `Sleep`
    // future completes.
    //
    sleep.wait();
}

Hashed Timing Wheel

The hashed timing wheel timer is a coarse grained timer that is optimized for cases where the timeout range is relatively uniform and high precision is not needed. These requirements are very common with network related applications as most timeouts tend to be a constant range (for example, 30 seconds) and timeouts are used more as a safe guard than for high precision.

The timer is inspired by the paper by Varghese and Lauck.

A hashed wheel timer is implemented as a vector of "slots" that represent time slices. The default slot size is 100ms. As time progresses, the timer walks over each slot and looks in the slot to find all timers that are due to expire. When the timer reaches the end of the vector, it starts back at the beginning.

Given the fact that the timer operates in ticks, a timeout can only be as precise as the tick duration. If the tick size is 100ms, any timeout request that falls within that 100ms slot will be triggered at the same time.

A timer is assigned to a slot by taking the expiration instant and assigning it to a slot, factoring in wrapping. When there are more than one timeouts assigned to a given slot, they are stored in a linked list.

This structure allows constant time timer operations as long as timeouts don't collide. In other words, if two timeouts are set to expire at exactly num-slots * tick-duration time apart, they will be assigned to the same bucket.

The best way to avoid collisions is to ensure that no timeout is set that is for greater than num-slots * tick-duration into the future.

A timer can be configured with Builder.

Runtime details

When creating a timer, a thread is spawned. The timing details are managed on this thread. When Timer::set_timeout is called, a request is sent to the thread over a bounded channel.

All storage needed to run the timer is pre-allocated, which means that the timer system is able to run without any runtime allocations. The one exception would be if the timer's max_capacity is larger than the initial_capacity, in which case timeout storage is allocated in chunks as needed. Timeout storage can grow but never shrink.

Structs

Builder

Configures and builds a Timer

Interval

A stream representing notifications at fixed interval

Sleep

A Future that does nothing and completes after the requested duration

Timeout

Allows a given Future to execute for a max duration

TimeoutStream

Allows a given Stream to take a max duration to yield the next value.

Timer

A facility for scheduling timeouts

Enums

TimeoutError

The error type for timeout operations.

TimerError

The error type for timer operations.

Functions

wheel

Configure and build a Timer backed by a hashed wheel.