YmerNode.Schedules.Scheduler (Ymer Node v0.5.0)

Copy Markdown View Source

The process that fires schedules: once a minute, on the minute, it reads the active schedules and starts a firing for each one due in that minute — each in a task of its own under YmerNode.Schedules.FiringSupervisor, so a long run never holds the next minute back.

The next firing is carried, not recomputed

For each schedule the process keeps the next firing it expects, and walks the cron expression again only when that firing comes due or has gone by: one walk a firing, rather than one a minute for every schedule. What is carried is not what keeps a time from firing twice when the clock falls back — YmerNode.Schedules.Cron.next_firing/2 never answers the second pass of a repeated hour, from whichever minute it is asked — so a restart, or a changed expression found afresh, fires nothing a carried walk would not have.

A next firing already gone by when its minute is read — the node was asleep, or not yet up — is dropped, and the next one is found from the minute at hand: a missed firing is skipped, never caught up. The carried firings live in this process and nowhere else, so a restart starts again from the minute it comes up. They are keyed by schedule and cron expression, so an update that changes the expression is found afresh.

plan/4 is that decision — a deterministic function of the carried firings, the schedules and the minute — and the process is the clock around it.

config/test.exs turns the process off (enabled?/0): it would read the node database every minute with no sandbox owner. The suite drives plan/4 and YmerNode.Schedules.fire/2 itself, and hands handle_info/2 one minute by hand, inside a case's own sandbox, for the wiring between them.

Summary

Functions

Returns a specification to start this module under a supervisor.

Whether the scheduler runs (config :ymer_node, YmerNode.Schedules.Scheduler, :enabled). Defaults to enabled; config/test.exs turns it off.

Decides one minute: the schedules that fire at minute, and the next firing each schedule carries into the minutes after it.

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

enabled?()

Whether the scheduler runs (config :ymer_node, YmerNode.Schedules.Scheduler, :enabled). Defaults to enabled; config/test.exs turns it off.

plan(carried, schedules, minute, zone)

Decides one minute: the schedules that fire at minute, and the next firing each schedule carries into the minutes after it.

carried is the previous call's second element, %{} at the start. minute is a UTC DateTime on the minute, read in zone, and schedules are the active ones; a schedule no longer among them drops out of what is carried.

start_link(options)