Zizq.Cron (Zizq v0.6.0)

Copy Markdown View Source

A named group of scheduled jobs.

The same struct is used for both input and what the server returns, so installing a schedule and amending one use the same shape:

Zizq.Cron.new("my_app")
|> Zizq.Cron.put_entry(
  name: "nightly_cleanup",
  expression: "0 3 * * *",
  job: MyApp.Cleanup.new(%{})
)
|> Zizq.replace_cron(MyApp.Zizq)

Declared all at once instead, if that reads better:

Zizq.Cron.new("my_app",
  entries: [
    [name: "nightly_cleanup", expression: "0 3 * * *", job: MyApp.Cleanup.new(%{})]
  ]
)
|> Zizq.replace_cron(MyApp.Zizq)

Groups exist so a schedule can be replaced, paused or removed as a unit — typically one group per application, holding every entry that application owns.

Normally the schedule lives in code and is installed on boot. Installing is atomic and idempotent, so every instance of an application can do it on startup without coordinating.

Amending a schedule already on the server

A schedule can also be read, changed and put back:

Zizq.get_cron!("my_app", MyApp.Zizq)
|> Zizq.Cron.delete_entry("nightly_cleanup")
|> Zizq.replace_cron(MyApp.Zizq)

This suits one-off changes made by one operator. It reads and writes as two steps, so it is not the way to make a change from running application code where several instances might do it at once — for that, Zizq.pause_cron_entry/2 and Zizq.delete_cron_entry/2 change a single entry in one request.

Fields

  • :name — the group's name.
  • :entries — the Zizq.CronEntry structs it holds. Each names its own :timezone; there is no group-level default, because the server has nowhere to keep one and it would be lost the moment a schedule was read back.
  • :paused — whether the whole group is suspended. A paused group fires nothing, whatever its entries say. Left nil, an existing group keeps its current state and a new one starts running.
  • :paused_at, :resumed_at — when it was last suspended and resumed. Read-only.

Summary

Functions

Remove an entry by name. Removing one that is not there changes nothing.

Look up one entry by name, or nil.

Build a schedule.

Add an entry, or replace the one with that name.

Types

t()

@type t() :: %Zizq.Cron{
  entries: [Zizq.CronEntry.t()],
  name: String.t() | nil,
  paused: boolean() | nil,
  paused_at: DateTime.t() | nil,
  resumed_at: DateTime.t() | nil
}

Functions

delete_entry(cron, name)

@spec delete_entry(t(), String.t()) :: t()

Remove an entry by name. Removing one that is not there changes nothing.

entry(cron, name)

@spec entry(t(), String.t()) :: Zizq.CronEntry.t() | nil

Look up one entry by name, or nil.

new(name, opts \\ [])

@spec new(
  String.t(),
  keyword()
) :: t()

Build a schedule.

Options

  • :entriesZizq.CronEntry structs, keyword lists or maps.
  • :paused — whether the group starts suspended.

put_entry(cron, entry)

@spec put_entry(t(), Zizq.CronEntry.t() | keyword() | map()) :: t()

Add an entry, or replace the one with that name.

Upsert rather than append, so putting the same schedule twice leaves one entry — the behaviour the whole group already has when installed twice.