Module timer Timer module that supports one-time timer, periodic timer and Cron-compatible syntax.

Type timer

timer.cancel(timer) Rearms a canceled or expired timer.
timer.cron(cron, hook, varargs) Creates a new timer object, which will elapse at every date described by the cron parameter.
timer.cron_nextevent(timer) Converts a CRON string into the next date at which the corresponding event shall be triggered.
timer.latencyExec(func, latency) Calls a function within a maximum delay, while trying to avoid multiple calls.
timer.nbofdaysinmonth(date) Retrieves the number of days in the month including a given date.
timer.new(expiry, hook, varargs) Setups and returns a new timer object.
timer.nextval(p, curr, period, minval) Converts a CRON element, already extracted from the string, into a number representing the next occurrence.
timer.once(delay, hook, varargs) Creates a new timer object, which will elapse after delay seconds.
timer.periodic(period, hook, varargs) Creates a new timer object, which will elapse every period seconds.

Type timer

Field(s)

timer.cancel(timer)

Rearms a canceled or expired timer.
Same as new function. A signal will be emitted on timer expiration.

Parameter

Return values

  1. "ok" on success.
  2. nil followed by an error message otherwise.

timer.cron(cron, hook, varargs)

Creates a new timer object, which will elapse at every date described by the cron parameter.
If a hook function is provided, it is run whenever the timer elapses. This is an alternative to #timer.new.

CRON specification strings

Cron entries are strings of 5 elements, separated by single spaces.

.---------------- minute (0 - 59) | .------------- hour (0 - 23) | | .---------- day of month (1 - 31) | | | .------- month (1 - 12) OR jan,feb,mar,apr ... | | | | .---- day of week (0 - 7) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat | | | | | .- optional random jitter | | | | | | * * * * * *

The corresponding event is triggered every minute at most, if and only if every field matches the current date. Asterisks ("*") can be used as placeholderst in unused fields. For instance, "30 8 1 * * *" describes an event which takes place at 8:30AM every first day of the month.

Beside numbers, some operators are allowed in fields:

For instance, "0 * * * *" denotes an event at every hour (whenever the number of minutes reaches 0), but "0 */6 * * *" denotes only the hours divisible by 6 (i.e. 0:00, 6:00, 12:00 and 18:00). Beware that the formal meaning of the '/' operator is "whenever the modulo is 0". As a consequence, "*/61" in the minutes slot will be triggered when the number of minutes reaches 0, because 0/61==0.

Cron also accepts some aliases for common periodicities. "@hourly", "@daily", "@weekly", "@monthly"and "@annually" represent the corresponding expected periodic events.

CRON jitter extension

timer.cron() supports an addition to the cron standard: if a sixth number element is appended to the string, this number is taken as a random jitter, in seconds. For instance, if a jitter of 120 is given, a random shifting between 0 and 120 is chosen when the timer is created; every triggerring of the event will be time-shifted by this amount of time.

The jitter doesn't change during the lifetime of a given timer: if a minutely test "* * * * * 59" is triggered at 12:03:28, it will be triggered next at 12:04:28, 12:05:28 etc.: jitters don't modify the time which elapses between the triggerings of a given timer.

Jitter allows to spread the triggering dates of resource-intensive operations. For instance, if a communication to the M2M operating portal is scheduled at midnight with "0 0 * * *" on a large fleet of devices, congestion might ensue on the communication networks and/or on the servers. By adding a 60604 = 14400 jitter, communications will be uniformly spread between 0:00AM and 04:00AM: "0 0 * * * 14400".

CRON specified with a table

Cron specifications can also be entered as tables, with keys `minute, hour, dayofmonth, dayofweek, jitter` respectively; missing keys are treated as "*" (except for jitter, which is treated as missing); lists of values are passed as tables; steps and ranges are not supported in any special ways, but they can be passed as strings, e.g. { hour='9-12,14-17', minute=0 }.

Parameters

Return value

a timer object

timer.cron_nextevent(timer)

Converts a CRON string into the next date at which the corresponding event shall be triggered.
To be stored as a timer object's nextevent field.

Parameter

Return value

next occurrence's date, as an os.time() number.

timer.latencyExec(func, latency)

Calls a function within a maximum delay, while trying to avoid multiple calls.
In some cases, a task must be performed within the next n seconds; if the task is performed by calling function f, then a call to timer.latencyexec(f, n) will guarantee that. If f hasn't been run after the n seconds delay expired (neither by this thread nor any other one), then the execution of f is triggered. However, if f has already been triggered by another call to timer.latencyexec before the delay expired, then it isn't triggered a second time.

When a function can treat data by batches and is idempotent (think for instance flushing buffered data to a server), calling it with a delay through latencyexec leaves a chance to group multiple invocations into a single one, thus presumably saving resources.

Parameters

Return values

  1. "ok" on success.
  2. nil followed by an error message otherwise.

Usage:


 timer.latencyExec examples

 -- t1: `f` must have run within the next 10s
 timer.latencyexec(f, 10)
 -- t2: `f` must have run within the next 5s. This supercedes t1
 timer.latencyexec(f, 5)
 -- after 3s elapsed, `f` must run within the next 5s-3s=2s
 sched.wait(3)
 -- t3: `f` must have run within the next 1s. This supercedes the 2s left in t2
 t3 = timer.latencyexec(f, 1)
 -- `f` will run in the middle of this 2s delay, due to t3
 sched.wait(2)
 -- This has been scheduled after t3 elapsed, so `f` will be run again in 1s at most.
 t4 = timer.latencyexec(f, 1)

timer.nbofdaysinmonth(date)

Retrieves the number of days in the month including a given date.

Parameter

Return value

number of days in the month: 28,29,30,31

timer.new(expiry, hook, varargs)

Setups and returns a new timer object.

This function can be called directly instead of timer.once, timer.periodic and timer.cron.

The event will cause a signal([returned timer], 'run') whenever its due date(s) is/are reached. The date(s) is/are determined by the expiry argument:

Parameters

Return values

  1. created timer on success.
  2. nil followed by an error message otherwise.

timer.nextval(p, curr, period, minval)

Converts a CRON element, already extracted from the string, into a number representing the next occurrence.
This number's unit is the same as the string's, hence can be in minutes, hours etc.

Parameters

Return value

time of next occurrence of the event, in the same units as p.

timer.once(delay, hook, varargs)

Creates a new timer object, which will elapse after delay seconds.
If a hook function is provided, it is run when the timer elapses.

Parameters

timer.periodic(period, hook, varargs)

Creates a new timer object, which will elapse every period seconds.
If a hook function is provided, it is run whenever the timer elapses.

Parameters