Packages
quantum
1.9.2
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/normalizer.ex
defmodule Quantum.Normalizer do
@moduledoc false
def normalize(j) do
nj = normalize_job(j)
{nj.name, nj}
end
def default_nodes do
Application.get_env(:quantum, :default_nodes, [node()])
end
# Creates named Quantum.Job
# Input:
# [
# newsletter: [
# schedule: "* * * * *",
# task: "MyModule.my_method",
# args: [1, 2, 3]
# ]
# ]
# Output:
# %Quantum.Job{
# name: :newsletter,
# schedule: "* * * * *",
# task: {"MyModule", "my_method"},
# args: [1, 2, 3]
# }
defp normalize_job({job_name, %Quantum.Job{} = job}) do
# Sets defauts for job and normalizes values
job |> Map.merge(job_opts(job_name, Map.to_list(job)))
end
defp normalize_job({job_name, opts}) when opts |> is_list or opts |> is_map do
%Quantum.Job{} |> Map.merge(job_opts(job_name, opts))
end
# Creates unnamed Quantum.Job
# Input:
# "* * * * * MyModule.my_method"
# OR
# "* * * * *": {MyModule, "my_method"}
# OR
# "* * * * *": &MyModule.my_method/0
# Output:
# %Quantum.Job{
# name: :__unnamed__,
# schedule: "* * * * *",
# task: {"MyModule", "my_method"} / &MyModule.my_method/0,
# args: []
# }
defp normalize_job(j) do
opts = case normalize_unnamed_job(j) do
{schedule, task, args} -> %{schedule: schedule, task: task, args: args}
{schedule, task} -> %{schedule: schedule, task: task}
end
normalize_job({nil, opts})
end
# Converts a job {expr, fun} into its canonical format.
# Cron expression is converted to lowercase string and
# day and month names are translated to their indexes.
defp normalize_unnamed_job({e, fun}) do
schedule = normalize_schedule(e)
case normalize_task(fun) do
{mod, fun, args} -> {schedule, {mod, fun}, args}
fun -> {schedule, fun}
end
end
# Converts a string representation of schedule+job into
# its canonical format.
# Input: "* * * * * MyApp.MyModule.my_method"
# Output: {"* * * * *", {"MyApp.MyModule", "my_method"}}
defp normalize_unnamed_job(e) do
[[_, schedule, task]] =
~r/^(\S+\s+\S+\s+\S+\s+\S+\s+\S+|@\w+)\s+(.*\.\w+)$/
|> Regex.scan(e)
{normalize_schedule(schedule), normalize_task(task)}
end
# Converts string representation of task into its
# canonical format
# Input: "MyApp.MyModule.my_method"
# Output: {"MyApp.MyModule", "my_method"}
defp normalize_task(t) when t |> is_binary do
[[_, mod, fun]] = Regex.scan(~r/^(.*)\.(\w+)$/, t)
{mod, fun}
end
defp normalize_task({mod, fun, args}), do: {mod, fun, args}
defp normalize_task({mod, fun}), do: {mod, fun}
defp normalize_task(fun), do: fun
defp normalize_schedule(e = %Crontab.CronExpression{}), do: e
defp normalize_schedule(e) when e |> is_atom, do: e |> Atom.to_string |> normalize_schedule
defp normalize_schedule("nil"), do: nil
defp normalize_schedule(e) when e |> is_binary, do: e |> String.downcase |> Crontab.CronExpression.Parser.parse!
# Extracts given option from options list of named task
defp extract(name, opts, d \\ nil)
defp extract(name, opts, d) when opts |> is_list, do: extract(name, opts |> Enum.into(%{}), d)
defp extract(:schedule, opts, d), do: opts |> Map.get(:schedule, d) |> normalize_schedule
defp extract(:task, opts, d), do: opts |> Map.get(:task, d) |> normalize_task
defp extract(:nodes, opts, d), do: opts |> Map.get(:nodes, d) || d
defp extract(name, opts, d), do: opts |> Map.get(name, d)
defp atomize(list) when is_list(list), do: Enum.map(list, &atomize/1)
defp atomize(string) when is_binary(string), do: String.to_atom(string)
defp atomize(atom) when is_atom(atom), do: atom
defp job_opts(job_name, opts) do
overlap = Application.get_env(:quantum, :default_overlap, true)
%{
name: job_name,
schedule: extract(:schedule, opts),
task: extract(:task, opts),
args: extract(:args, opts, []),
overlap: extract(:overlap, opts, overlap),
nodes: :nodes |> extract(opts, default_nodes()) |> atomize
}
end
end