Packages
quantum
1.5.0
3.5.3
3.5.2
retired
3.5.1
retired
3.5.0
3.4.0
3.3.0
3.2.0
3.1.0
3.0.2
3.0.1
3.0.0
3.0.0-rc.3
3.0.0-rc.2
3.0.0-rc.1
2.4.0
2.3.4
2.3.3
2.3.2
2.3.1
retired
2.3.0
retired
2.2.7
2.2.6
2.2.5
retired
2.2.4
retired
2.2.3
retired
2.2.2
retired
2.2.1
retired
2.2.0
retired
2.1.3
retired
2.1.2
retired
2.1.1
retired
2.1.0
retired
2.1.0-beta.1
retired
2.0.4
retired
2.0.3
retired
2.0.2
retired
2.0.1
retired
2.0.0
retired
2.0.0-beta.2
retired
2.0.0-beta.1
retired
1.9.3
retired
1.9.2
retired
1.9.1
retired
1.9.0
retired
1.8.1
retired
1.8.0
retired
1.7.1
retired
1.7.0
retired
1.6.1
retired
1.6.0
retired
1.5.0
retired
1.4.0
retired
1.3.2
retired
1.3.1
retired
1.3.0
retired
1.2.4
retired
1.2.3
retired
1.2.2
retired
1.2.1
retired
1.2.0
retired
1.1.0
retired
1.0.4
retired
1.0.3
retired
1.0.2
retired
1.0.1
retired
1.0.0
retired
Cron-like job scheduler for Elixir.
Retired package: Security issue - v1 is no longer supported
Current section
Files
Jump to
Current section
Files
lib/quantum.ex
defmodule Quantum do
use GenServer
@typedoc "A cron expression"
@type expr :: String.t | Atom
@typedoc "A function/0 to be called when cron expression matches"
@type fun0 :: (() -> Type)
@typedoc "A job is defined by a cron expression and a task"
@type job :: {atom, Quantum.Job.t}
@typedoc "A job options can be defined as list or map"
@type opts :: list | map | fun0
@doc "Adds a new unnamed job"
@spec add_job(job) :: :ok
def add_job(job) do
GenServer.call(Quantum, {:add, Quantum.Normalizer.normalize({nil, job})})
end
@doc "Adds a new named job"
@spec add_job(expr, job) :: :ok
def add_job(expr, job) do
GenServer.call(Quantum, {:add, Quantum.Normalizer.normalize({expr, job})})
end
@doc "Deactivates a job by name"
@spec deactivate_job(expr) :: :ok
def deactivate_job(n) do
GenServer.call(Quantum, {:change_state, n, :inactive})
end
@doc "Activates a job by name"
@spec activate_job(expr) :: :ok
def activate_job(n) do
GenServer.call(Quantum, {:change_state, n, :active})
end
@doc "Resolves a job by name"
@spec find_job(expr) :: job
def find_job(name) do
Keyword.get(jobs, name)
end
@doc "Deletes a job by name"
@spec delete_job(expr) :: job
def delete_job(name) do
GenServer.call(Quantum, {:delete, name})
end
@doc "Returns the list of currently defined jobs"
@spec jobs :: [job]
def jobs do
GenServer.call(Quantum, :jobs)
end
@doc "Starts Quantum process"
def start_link(state) do
GenServer.start_link(__MODULE__, state, [name: Quantum])
end
def init(s) do
Quantum.Timer.tick
{:ok, %{s | jobs: run(%{s | r: 1}), r: 0}}
end
def handle_call({:add, j}, _, s), do: {:reply, :ok, %{s | jobs: [j | s.jobs]}}
def handle_call({:change_state, n, js}, _, s) do
jobs = Enum.map(s.jobs, fn({jn, j}) ->
case jn do
^n -> {jn, %{j | state: js}}
_ -> {jn, j}
end
end)
{:reply, :ok, %{s | jobs: jobs}}
end
def handle_call({:delete, n}, _, s) do
job = case Keyword.get(s.jobs, n) do
nil -> nil
job ->
s = %{s | jobs: Keyword.delete(s.jobs, n)}
job
end
{:reply, job, s}
end
def handle_call(:jobs, _, s), do: {:reply, s.jobs, s}
def handle_call(:which_children, _, s) do
children = [{Task.Supervisor, :quantum_tasks_sup, :supervisor, [Task.Supervisor]}]
{:reply, children, s}
end
def handle_info(:tick, s) do
{d, h, m} = Quantum.Timer.tick
if s.d != d, do: s = %{s | d: d, w: rem(:calendar.day_of_the_week(d), 7)}
s = %{s | h: h, m: m}
{:noreply, %{s | jobs: run(s)}}
end
def handle_info(_, s), do: {:noreply, s}
defp run(s) do
Enum.each s.jobs, fn({_name, j}) ->
if j.state == :active && node() in j.nodes do
Task.Supervisor.async(:quantum_tasks_sup, Quantum.Executor, :execute,
[{j.schedule, j.task, j.args}, s])
end
end
s.jobs
end
end