Keep the schedules in a file
The agent gets schedules: a task with one local time or a cron
expression. agent/schedules.json holds them, and each set and remove
writes it whole with mode 0600 before it returns, so a schedule survives
a restart. The file keeps the last ID, so that an ID is never used
again. A mutex protects the schedules, because the tools change them
from a turn while the runs read them.
A one-time time is a local wall time after now. A time in the hour that
the clock repeats is its first occurrence, as in cron. The cron
expressions are checked at a set and at the start.
A run ends with Done: a one-time schedule goes, and a repeating one gets
the next time after now, so a repeating schedule that missed several
times while the daemon was stopped runs once. The message of a run names
the schedule, gives its time and the task, says when the run is more
than one minute late, and ends with the line about the empty reply, as a
WhatsApp batch does.
Issue:
60e4e4f