CandleClock (candle_clock v1.4.0) View Source
CandleClock manages timers that persist even across restarts.
Core concepts
Timer
A timer is a function call that will happen at some point in the future. It always contains an MFA and either a duration, an interval or a crontab expression.
MFA
An MFA is a tuple with 3 elements: the module, the function and the
arguments to pass to the function. The 3 elements of the tuple are the same as
the 3 arguments you'd pass to Kernel.apply/3
.
Crontab
A crontab expression can be used when you want the timer to trigger at regular dates or times, such as
- Every monday at 12 AM:
0 12 * * 1
- Every 5 minutes:
*/5 * * * *
- Every hour:
0 * * * *
- Every day at 5 PM:
0 17 * * *
Timers with crontabs can be given an additional time zone so 0 17 * * *
for
Europe/Berlin
is 16:00 UTC during winter time but 15:00 UTC during summer
time.
Startup behaviour
At startup, all timers that have an expired_at
date in the past will be
executed.
When planning the next execution time of a single timer, it will take the last execution time as the basis. However, that might lead to a timer being called multiple times directly after a long downtime.
For that reason, if :skip_if_offline
is true, interval and cron timers will
instead be planned to the next time it would've happened as if the earlier
intervals would've been triggered as well, but they won't be called more than
once at startup.
:skip_if_offline
is enabled by default.
Duration and intervals
All durations and intervals are integers in the unit millisecond.
Common options
These are the common options that can be passed to call_after/3
,
call_interval/4
and call_crontab/4
:
:name
(string) A name that makes this timer unique. Unique timers will be replaced when a new timer with the same name is created. That way, a defer can be implemented simply by always giving the same name.:if_not_exists
(bool, default:false
) If set to true, will not create the timer if one already exists with that name. Requires aname
to be set.:skip_if_offline
(bool, default:true
) If set to false, interval and cron timers behave differently after a long downtime of the system. See also: Startup behaviour:max_calls
(int, default:nil
or1
for duration timers) Controls the maximum amount this timer can be called before it is cancelled. Not supported in duration timers started withcall_after/3
.
Link to this section Summary
Functions
Creates a timer that is executed after the duration in milliseconds.
Creates a timer that is executed according to the given crontab schema.
Creates a timer that is executed every interval
ms.
Cancels all timers that call the given module and function.
Cancels a timer by its ID.
Cancels the timer with the given name.
Creates a list of timers at once (using insert_all).
Returns if a timer with the given id exists
Returns if a timer with the given name exists
Calculates the next expiry date for the given timer from the given date onwards.
Link to this section Types
Specs
alarm_spec() :: %{expires_at: DateTime.t(), max_calls: 1}
Specs
argument() :: any()
Specs
arguments() :: [argument()]
Specs
cron_timer_spec() :: %{ crontab: Crontab.CronExpression.t(), crontab_timezone: binary() }
Specs
duration_timer_spec() :: %{duration: non_neg_integer(), max_calls: 1}
Specs
interval() :: non_neg_integer()
Specs
interval_timer_spec() :: %{ duration: non_neg_integer(), interval: non_neg_integer(), max_calls: nil | non_neg_integer() }
Specs
Specs
timer_spec() :: cron_timer_spec() | duration_timer_spec() | interval_timer_spec() | alarm_spec()
Link to this section Functions
Specs
Creates a timer that is executed after the duration in milliseconds.
Returns the timer in an ok-tuple if successful.
Specs
call_at(mf_args(), DateTime.t(), keyword()) :: {:ok, struct()} | {:error, any()}
Specs
Creates a timer that is executed according to the given crontab schema.
Returns the timer in an ok-tuple if successful.
Specs
Creates a timer that is executed every interval
ms.
Additionally, the duration until the first trigger can be passed with the
duration
argument.
Returns the timer in an ok-tuple if successful.
Specs
cancel_all(module(), atom()) :: {:ok, non_neg_integer()}
Cancels all timers that call the given module and function.
Returns {:ok, amount}
if successful, where amount is the number of timers
that were cancelled.
Specs
cancel_by_id(any()) :: {:ok, non_neg_integer()}
Cancels a timer by its ID.
Returns {:ok, 1}
if the ID matched.
Specs
cancel_by_name(String.t()) :: {:ok, non_neg_integer()}
Cancels the timer with the given name.
Returns {:ok, 1}
if a timer with that name was found.
Specs
create_many([timer_spec()], keyword()) :: [struct()]
Creates a list of timers at once (using insert_all).
Schemas for the different timer types:
For all timer types
%{
module: module(),
function: atom(),
arguments: list(),
inserted_at: DateTime.t(),
updated_at: DateTime.t()
}
as well as any custom fields defined in the candle clock timer schema.
Duration
%{
duration: non_neg_integer(), # milliseconds
max_calls: 1
}
Interval
%{
duration: non_neg_integer(), # milliseconds
interval: non_neg_integer(), # milliseconds
max_calls: nil | non_neg_integer() # nil for unlimited calls
}
Once, at a specific date and time
%{
expires_at: DateTime.t(),
max_calls: 1
}
Cron
%{
crontab: Crontab.CronExpression.t(),
crontab_timezone: binary() # "Europe/Berlin" for example.
}
Specs
Returns if a timer with the given id exists
Specs
Returns if a timer with the given name exists
Specs
next_expiry( struct(), DateTime.t() ) :: {:ok, DateTime.t()} | {:error, any()}
Calculates the next expiry date for the given timer from the given date onwards.
Returns {:ok, datetime}
or an error-tuple