Module timerwheel

Timer wheel implementation

Efficient timer for timeout related timers: fast insertion, deletion, and execution (all as O(1) implemented), but with lesser precision.

This module will not provide the timer/runloop itself. Use your own runloop and call wheel:step to check and execute timers.

Implementation: Consider a stack of rings, a timer beyond the current ring size is in the next ring (or beyond). Precision is based on a slot with a specific size.

The code explicitly avoids using pairs, ipairs and next to ensure JIT compilation when using LuaJIT

Functions

new (opts) Creates a new timer wheel.
wheel:cancel (id) Cancels a timer.
wheel:count () Gets the number of timers.
wheel:peek ([max_ahead]) Looks up the next expiring timer.
wheel:set (expire_in, cb, arg) Sets a timer.
wheel:step () Checks and executes timers.


Functions

new (opts)
Creates a new timer wheel.

Parameters:

  • opts the options table
    • precision number the precision of the timer wheel in seconds (slot size), (default 0.050)
    • ringsize int number of slots in each ring, defaults to 72000 (1 hour span, with precision == 0.050) (optional)
    • now function a function returning the curent time in seconds. Defaults to ngx.now or luasocket.gettime if available. (optional)
    • err_handler function a function to use as error handler in an xpcall when executing the callback. The default will write the stacktrace to stderr. (optional)

Returns:

    wheel the timerwheel object
wheel:cancel (id)
Cancels a timer.

Parameters:

  • id int the timer id to cancel

Returns:

    boolean true if cancelled, false if not found
wheel:count ()
Gets the number of timers.

Returns:

    int number of timers
wheel:peek ([max_ahead])
Looks up the next expiring timer. Note: traverses the wheel, O(n) operation!

Parameters:

  • max_ahead number maximum time (in seconds) to look ahead (optional)

Returns:

    number number of seconds until next timer expires (can be negative), or 'nil' if there is no timer from now to max_ahead

Usage:

    local t = wheel:peek(10)
    if t then
      print("next timer expires in ", t," seconds")
    else
      print("no timer scheduled for the next 10 seconds")
    end
wheel:set (expire_in, cb, arg)
Sets a timer.

Parameters:

  • expire_in number in how many seconds should the timer expire
  • cb function callback function to execute upon expiring (NOTE: the callback will run within an xpcall)
  • arg parameter to be passed to cb when executing

Returns:

    int the id of the newly set timer

Usage:

    local cb = function(arg)
      print("timer executed with: ", arg)  --> "timer executed with: hello world"
    end
    local id = wheel:set(5, cb, "hello world")
    
    -- do stuff here, while regularly calling wheel:step()
    
    wheel:cancel(id)  -- cancel the timer again
wheel:step ()
Checks and executes timers. Call this function (at least) every precision seconds.

Returns:

    true
generated by LDoc 1.4.6 Last updated 2022-11-03 17:31:27