Ratchet Library :: Advanced Timers
API  ·  Manual

ratchet.timerfd API Reference


When an application needs to trigger timers on a regular basis, perhaps to do some cleanup every minute or poll for changes, a simple timer could work, but has some disadvantages. Specifically, whatever code executes after the timer triggers but before its scheduled again takes time. Say you wait 60 seconds, then do 10 seconds of processing, then wait another 60 seconds, and so on. It would take 7 minutes to do 6 iterations, and may throw the whole system off. Or perhaps you'd like to update something every 5 seconds, but the update process may take 20-30 seconds, an advanced timer will tell you how many ticks of the timer have elapsed since you last acted on it.

To create a timer, call ratchet.timerfd.new(). As with the timerfd system calls, the constructor must define whether the timer depends on the system clock (as in, if a user changes their system clock, what happens to the timer). The default is for the timer to be independent of the system clock, but that can be changed by passing "realtime" to the constructor or forced by passing "monotonic".

local tfd = ratchet.timerfd.new()

Arm, Disarm, and Query

On creation, the timer is disarmed and will not tick. To arm the timer, pass a non-zero floating-point number of seconds to timerfd:settime(). This will instantly start the timer in the background, but will not pause the current thread. If you pass a non-zero floating-point number as a second argument, the timer will not disarm after the first elapsing and will instead reset to that many seconds. Passing no arguments (or zero as the first argument) will instantly disarm the timer.

To query the time until the next timer tick, call timerfd:gettime(). This will return that value as a floating-point number, followed by the interval in seconds that the timer will keep ticking.

-- Arm the timer for 30 seconds from now, and keep resetting to 30 seconds.
tfd:settime(30.0, 30.0)

-- Do some processing...

local time_left = tfd:gettime()


While querying the timer may be useful, the true power of advanced timers is in the monitoring ability. This allows the current thread to be paused until the next tick of the timer, or tell how many times the timer has ticked since the monitoring call.

To monitor an advanced timer, use the timerfd:read() method. Behind the scenes, this function actually calls the read() system call, hence the name. If the timer has fired since the last call, this call will potentially yield control to other threads, but should return near immediately with the number of ticks since the last call. Otherwise, this call will wait until the next tick of the timer and return 1.

-- Arm the timer for 5 seconds, and keep resetting to 5 seconds.
tfd:settime(5.0, 5.0)

-- Do 60 seconds of processing...

local ticks = tfd:read()    -- would return 12 right away
tfd:read()    -- pauses thread until next 5 second tick

Last modified:  Sun, 17 Aug 2014 09:32:32 -0400
Author:  ian.good