erlcron (erlcron v1.3.6)
Erlcron is a testable cron-like job scheduler for Erlang applications.
Each scheduled job runs in its own lightweight process that sleeps for exactly the computed duration until its next execution time, giving millisecond precision instead of the one-minute polling interval used by Unix cron.
The scheduler clock can be manipulated at runtime with
set_datetime/1 and multi_set_datetime/1. When the clock is
advanced, all jobs whose scheduled time falls within the elapsed
interval are executed in order, which makes it straightforward to test
time-based behaviour in automated test suites.
Schedule types
{once, When}— Run a job exactly once at the given time or after the given number of seconds.{daily, Period}— Run a job every day at the given time, list of times, or on a recurring schedule optionally bounded by a time window.{weekly, DOW, Period}— Run a job on the specified day(s) of the week.DOWis a day atom (mon..sun) or a list of day atoms.{monthly, DOM, Period}— Run a job on the specified day(s) of the month. Positive integers count from the start of the month;0and negative integers count backwards from the last day (0= last day,-1= second-to-last, and so on).CronExpr— A standard 5-field Unix cron expression as a string or binary (e.g."30 9 * * 1",<<"*/5 * * * *">>). The expression is parsed viaecrn_util:from_cron/1into an equivalent erlcron tuple schedule at job-submission time. Seeecrn_util:from_cron/1for supported syntax and the mapping to erlcron schedule forms.
When
When specifies a point in time. It is used as the argument to
{once, When} and to the convenience functions at/2, daily/2,
weekly/3, and monthly/3.
A When value can be any of:
| Form | Example | Meaning |
|---|---|---|
{H, am|pm} | {3, pm} | 3:00:00 PM (15:00:00) |
{H, M, am|pm} | {3, 30, pm} | 3:30:00 PM (15:30:00) |
{H, M, S, am|pm} | {3, 30, 15, pm} | 3:30:15 PM (15:30:15) |
{H, M, S} | {15, 30, 0} | 24-hour clock time |
Seconds | 3600 | Number of seconds from now (for once only) |
Period
Period is used wherever a repeating or multi-time schedule is
needed (daily, weekly, monthly). It can take any of these forms:
| Form | Example | Meaning |
|---|---|---|
When | {3, 30, pm} | Run once per day at the given time |
[When] | [{9, am}, {5, pm}] | Run at each listed time per day |
{every, Duration} | {every, {30, min}} | Repeat every duration, all day |
{every, Duration, {between, From, To}} | {every, {5, min}, {between, {9, am}, {5, pm}}} | Repeat every duration within the time window |
Duration units: hr / h, min / m, sec / s.
Quick start
%% Start the application first
application:ensure_all_started(erlcron),
%% Run a fun once at 3:30 PM
erlcron:cron({{once, {3, 30, pm}}, fun() -> io:fwrite("Hello!~n") end}),
%% Run a fun every 5 minutes using a Unix cron expression
erlcron:cron({"*/5 * * * *", fun() -> poll() end}),
%% Run a fun every day at 9 AM, identified by a named reference
erlcron:daily(my_daily_job, {9, am}, fun() -> do_work() end),
%% Cancel the daily job
erlcron:cancel(my_daily_job).
Summary
Types
A 5-field Unix cron expression string or binary.
Alias for job_opts/0. Default options applied to all jobs in the crontab.
Called after a job has finished executing.
Per-job options map.
A job reference. Can be a reference(), atom, or binary.
Called before a job is executed.
Functions
Schedule a job to run once at When.
Cancel the job identified by JobRef. Returns true if found, false otherwise.
Add a new job to the scheduler.
Schedule a job identified by JobRef.
Schedule a job with an explicit reference, schedule, task, and options.
Schedule a job to run every day at When.
Return the current erlcron datetime (universal) together with the corresponding millisecond epoch value.
Return the current erlcron time as milliseconds since the Unix epoch.
Return the current erlcron time as seconds since the Unix epoch.
Return the references of all currently running jobs.
Schedule a job to run every month on day DOM at When.
Set the scheduler clock on all connected nodes. See multi_set_datetime/2.
Set the scheduler clock to DateTime on the given Nodes.
Return the reference datetime used as the scheduler's clock base.
Reset the scheduler clock to the real system time.
Set the scheduler clock to DateTime (local time).
Set the scheduler clock to DateTime.
Validate a schedule spec without scheduling the job.
Schedule a job to run every week on DOW (day-of-week) at When.
Types
-type callable() :: fun(() -> term()) | fun((JobRef :: job_ref(), calendar:datetime()) -> term()).
A 5-field Unix cron expression string or binary.
Examples: \"*/5 * * * *\", \"30 9 * * 1\", ~\"0 18 * * fri\".
Parsed at job-submission time by ecrn_util:from_cron/1.
-type cron_opts() :: job_opts().
Alias for job_opts/0. Default options applied to all jobs in the crontab.
-type cron_time() :: {integer(), am | pm} | {integer(), integer(), am | pm} | calendar:time().
-type dom() :: integer().
-type dow_day() :: mon | tue | wed | thu | fri | sat | sun.
-type duration() :: {integer(), hr | h | min | m | sec | s}.
-type job_end() :: fun((JobRef :: job_ref(), Res :: {ok, term()} | {error, {Reason :: term(), Stack :: list()}}) -> term()).
Called after a job has finished executing.
Res is {ok, Result} on success, or {error, {Reason, StackTrace}}
if the job raised an exception.
-type job_opts() :: #{hostnames => [binary() | string()], id => term(), on_job_start => {Mod :: atom(), Fun :: atom()} | job_start(), on_job_end => {Mod :: atom(), Fun :: atom()} | job_end()}.
Per-job options map.
hostnames— List of hostnames on which the job is allowed to run. The job is silently ignored on any other host.id— An arbitrary identifier passed toon_job_startandon_job_endcallbacks.on_job_start—{Mod, Fun}or afun/1called before the job executes. Returnignoreto skip this execution.on_job_end—{Mod, Fun}or afun/2called after the job finishes. Receives(JobRef, {ok, Result} | {error, {Reason, Stack}}).
A job reference. Can be a reference(), atom, or binary.
When the reference is an atom, the job process is locally registered under that name, making it easy to cancel it by name later.
Called before a job is executed.
If the function returns ignore, the job will not be executed and
on_job_end will not be called.
-type milliseconds() :: integer().
-type period() :: cron_time() | {every, duration()} | {every, duration(), constraint()}.
-type seconds() :: integer().
Functions
-spec at(cron_time() | seconds(), task()) -> job_ref() | ignored | already_started | {error, term()}.
Schedule a job to run once at When.
When can be a cron_time/0 (e.g. {3, 30, pm}) or an integer
number of seconds from now.
Cancel the job identified by JobRef. Returns true if found, false otherwise.
Add a new job to the scheduler.
The job is described using a job/0 spec. Returns the job_ref/0
that can be used to cancel the job later.
-spec cron(job_ref(), job(), job_opts()) -> job_ref() | ignored | already_started | {error, term()}.
Schedule a job identified by JobRef.
The reference can be a reference(), atom, or binary. When it is an
atom the job process is locally registered under that name.
Returns ignored when the job is not permitted to run on the current host.
When called as cron(Sched, Task, Opts) a fresh reference is generated
automatically and Opts is a job_opts/0 map.
-spec cron(job_ref(), schedule(), task(), job_opts()) -> job_ref() | ignored | already_started | {error, term()}.
Schedule a job with an explicit reference, schedule, task, and options.
erlcron:cron(my_job, {daily, {9, am}}, fun() -> ok end, #{}).
erlcron:cron(my_job, \"30 9 * * 1-5\", fun() -> standup() end, #{}).
-spec daily(cron_time() | seconds(), function()) -> job_ref() | ignored | already_started | {error, term()}.
Schedule a job to run every day at When.
-spec datetime() -> {calendar:datetime(), milliseconds()}.
Return the current erlcron datetime (universal) together with the corresponding millisecond epoch value.
-spec epoch() -> milliseconds().
Return the current erlcron time as milliseconds since the Unix epoch.
-spec epoch_seconds() -> seconds().
Return the current erlcron time as seconds since the Unix epoch.
-spec get_all_jobs() -> [job_ref()].
Return the references of all currently running jobs.
-spec monthly(dom(), cron_time() | seconds(), function()) -> job_ref() | ignored | already_started | {error, term()}.
Schedule a job to run every month on day DOM at When.
Positive DOM values count from the start of the month; 0 means the
last day of the month, and negative values count backwards from the last
day (e.g. -1 is the second-to-last day).
-spec multi_set_datetime(calendar:datetime()) -> {Replies, BadNodes} when Replies :: [{node(), ok | {error, term()}}], BadNodes :: [node()].
Set the scheduler clock on all connected nodes. See multi_set_datetime/2.
-spec multi_set_datetime([node()], calendar:datetime()) -> {Replies, BadNodes} when Replies :: [{node(), ok | {error, term()}}], BadNodes :: [node()].
Set the scheduler clock to DateTime on the given Nodes.
Any jobs scheduled between the old and new time on each node are
executed immediately. Returns {Replies, BadNodes} in the same format
as gen_server:multi_call/3.
-spec ref_datetime() -> {calendar:datetime(), milliseconds()}.
Return the reference datetime used as the scheduler's clock base.
-spec reset_datetime() -> ok.
Reset the scheduler clock to the real system time.
-spec set_datetime(calendar:datetime()) -> ok.
Set the scheduler clock to DateTime (local time).
-spec set_datetime(calendar:datetime(), local | universal) -> ok.
Set the scheduler clock to DateTime.
TZ controls how DateTime is interpreted: local (default) or
universal. When the clock is advanced, all jobs scheduled between the
old and new time are executed immediately.
Validate a schedule spec without scheduling the job.
-spec weekly(dow(), cron_time() | seconds(), function()) -> job_ref() | ignored | already_started | {error, term()}.
Schedule a job to run every week on DOW (day-of-week) at When.