Module timer
Timer module that supports one-time timer, periodic timer and Cron-compatible syntax.
Type timer
timer.cancel(timer) |
Cancels a running timer. |
timer.cron(cron, hook, varargs) |
Creates a new timer object, which will elapse at every date described by
the |
timer.latencyExec(func, latency) |
Calls a function within a maximum delay, while trying to avoid multiple calls. |
timer.new(expiry, hook, varargs) |
Setups and returns a new timer object. |
timer.once(delay, hook, varargs) |
Creates a new timer object, which will elapse after |
timer.periodic(period, hook, varargs) |
Creates a new timer object, which will elapse every |
timer.rearm(timer) |
Rearms a canceled or expired timer. |
Type timer
Field(s)
- timer.cancel(timer)
-
Cancels a running timer.
No signal will be triggered with this timer object. A canceled timer can be rearmed using the rearm function.
Parameter
-
timer
: as returned by timer.new function.
Return values
-
"ok" on success.
-
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:
As mentionned, the asterisk (
'*'
) placeholder represents all possible values for a field. For example, an asterisk in the hour time field would be equivalent to 'every hour' (subject to matching other specified fields).The comma (
','
) is a binary operator which specifies a list of possible values, e.g."1,3,4,7,8"
(there must be no space around commas)The dash (
'-'
) is a binary operator which specifies a range of values. For instance,"1-6"
is equivalent to"1,2,3,4,5,6"
The slash (
'/'
) is a binary operator, called "step", which allows to skip a given number of values. For instance,"*/3"
in the hour field is equivalent to"0,3,6,9,12,15,18,21"
.
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 forjitter
, 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
-
cron
: specification of the cron dates, as a cron string or a table (see timer.new) -
hook
: optional function, run everytime the timer elapses -
varargs
: optional parameters forhook
Return value
a timer object
- 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 functionf
, then a call totimer.latencyexec(f, n)
will guarantee that. Iff
hasn't been run after then
seconds delay expired (neither by this thread nor any other one), then the execution off
is triggered. However, iff
has already been triggered by another call totimer.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
-
func
: function to run. -
latency
: optional number. Time to wait before running the function (in seconds), if set to O then the function is run asynchronously but as soon as possible. if set to nil, then the function is run synchronously.
Return values
-
"ok" on success.
-
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 supersedes 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 supersedes 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.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 theexpiry
argument:If
expiry
is a positive number, causes a 1-shot event after that delay, in seconds, has elapsed.If
expiry
is a negative number, causes a periodic event whose period is the (positive) opposite ofexpiry
, in seconds.If
expiry
is a string or a table, causes events at the dates described under the POSIX CRON format. Cf. timer.cron for a detailed description of the CRON format. assert
Parameters
-
expiry
: string or number specifying the timer's due date(s). See explanations above. -
hook
: an optional function which will be called whenever the timer is due. The hook is called in a new thread (thus blocking functions are allowed in it). -
varargs
: optional additional parameters, which will be passed to thehook
function when called.
Return values
-
created timer on success.
-
nil
followed by an error message otherwise.
- 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
-
delay
: the duration before the timer elapses, in seconds -
hook
: optional function, run when the timer elapses -
varargs
: optional parameters forhook
-
- 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
-
period
: the duration between two timer triggerrings, in seconds -
hook
: optional function, run everytime the timer elapses -
varargs
: optional parameters forhook
-
- timer.rearm(timer)
-
Rearms a canceled or expired timer.
Same as new function. A signal will be emitted on timer expiration. Rearming a timer that have not expired, reset it to its inital value.
Parameter
-
timer
: as returned by timer.new function.
Return values
-
"ok" on success.
-
nil followed by an error message otherwise.
-