From 485aaae8cd408be70bc3648bd4ff1f5b24ac8866 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonatan=20M=C3=A4nnchen?= Date: Thu, 24 Feb 2022 14:52:46 +0100 Subject: [PATCH] Job Config Options --- lib/quantum.ex | 27 +++++++++++++++++++-- lib/quantum/job.ex | 39 ++++++++++++++---------------- test/quantum/run_strategy_test.exs | 7 +++--- test/quantum_startup_test.exs | 16 ++++++------ 4 files changed, 54 insertions(+), 35 deletions(-) diff --git a/lib/quantum.ex b/lib/quantum.ex index d8fe44e..5f1bb34 100644 --- a/lib/quantum.ex +++ b/lib/quantum.ex @@ -225,6 +225,16 @@ defmodule Quantum do @doc """ Creates a new Job. The job can be added by calling `add_job/1`. + + ## Supported options + + * `name` - see `Quantum.Job.set_name/2` + * `overlap` - see `Quantum.Job.set_overlap/2` + * `run_strategy` - see `Quantum.Job.set_run_strategy/2` + * `schedule` - see `Quantum.Job.set_schedule/2` + * `state` - see `Quantum.Job.set_state/2` + * `task` - see `Quantum.Job.set_task/2` + * `timezone` - see `Quantum.Job.set_timezone/2` """ @callback new_job(opts :: Keyword.t()) :: Quantum.Job.t() @@ -296,7 +306,7 @@ defmodule Quantum do |> Kernel.then(fn config -> Keyword.update(config, :jobs, [], fn jobs -> jobs - |> Enum.map(&Normalizer.normalize(scheduler.new_job(config), &1)) + |> Enum.map(&Normalizer.normalize(scheduler.__new_job__([], config), &1)) |> remove_jobs_with_duplicate_names(scheduler) end) end) @@ -376,7 +386,20 @@ defmodule Quantum do end @impl behaviour - def new_job(config \\ config()), do: Job.new(config) + def new_job(opts \\ []), do: __new_job__(opts, config()) + + @doc false + def __new_job__(opts, config) do + config + |> Keyword.take([:overlap, :schedule, :state, :timezone, :run_strategy]) + |> Keyword.merge(opts) + |> Keyword.update!(:run_strategy, fn + {module, options} when is_atom(module) -> module.normalize_config!(options) + module when is_atom(module) -> module.normalize_config!(nil) + %_struct{} = run_strategy -> run_strategy + end) + |> Job.new() + end @impl behaviour def deactivate_job(server \\ __job_broadcaster__(), name) diff --git a/lib/quantum/job.ex b/lib/quantum/job.ex index 83d07de..c2d95f2 100644 --- a/lib/quantum/job.ex +++ b/lib/quantum/job.ex @@ -42,30 +42,26 @@ defmodule Quantum.Job do } # Takes some config from a scheduler and returns a new job + # Do not use directly, use `Scheduler.new_job/1` instead. + @doc false @spec new(config :: Keyword.t()) :: t def new(config) do - {run_strategy_name, options} = - case Keyword.fetch!(config, :run_strategy) do - {module, option} -> {module, option} - module -> {module, nil} + Enum.reduce( + [ + {&set_name/2, Keyword.get(config, :name, make_ref())}, + {&set_overlap/2, Keyword.fetch!(config, :overlap)}, + {&set_run_strategy/2, Keyword.fetch!(config, :run_strategy)}, + {&set_schedule/2, Keyword.get(config, :schedule)}, + {&set_state/2, Keyword.fetch!(config, :state)}, + {&set_task/2, Keyword.get(config, :task)}, + {&set_timezone/2, Keyword.fetch!(config, :timezone)} + ], + %__MODULE__{name: nil, run_strategy: nil, overlap: nil, timezone: nil}, + fn + {_fun, nil}, acc -> acc + {fun, value}, acc -> fun.(acc, value) end - - with run_strategy <- run_strategy_name.normalize_config!(options), - name <- make_ref(), - overlap when is_boolean(overlap) <- Keyword.fetch!(config, :overlap), - timezone when timezone == :utc or is_binary(timezone) <- - Keyword.fetch!(config, :timezone), - state when is_atom(state) <- Keyword.fetch!(config, :state), - schedule <- Keyword.get(config, :schedule) do - %__MODULE__{ - name: name, - overlap: Keyword.fetch!(config, :overlap), - timezone: Keyword.fetch!(config, :timezone), - run_strategy: run_strategy, - schedule: schedule, - state: state - } - end + ) end @doc """ @@ -86,6 +82,7 @@ defmodule Quantum.Job do """ @spec set_name(t, atom) :: t def set_name(%__MODULE__{} = job, name) when is_atom(name), do: Map.put(job, :name, name) + def set_name(%__MODULE__{} = job, name) when is_reference(name), do: Map.put(job, :name, name) @doc """ Sets a job's schedule. diff --git a/test/quantum/run_strategy_test.exs b/test/quantum/run_strategy_test.exs index 2efdb05..b8680de 100644 --- a/test/quantum/run_strategy_test.exs +++ b/test/quantum/run_strategy_test.exs @@ -11,21 +11,22 @@ defmodule Quantum.RunStrategyTest do end test "run strategy local" do - job = Job.new(Scheduler.config(run_strategy: Quantum.RunStrategy.Local)) + job = Scheduler.new_job(run_strategy: Quantum.RunStrategy.Local) assert %Job{} = job assert [Node.self()] == NodeList.nodes(job.run_strategy, job) end test "run strategy random" do node_list = [:node1, :node2] - job = Job.new(Scheduler.config(run_strategy: {Quantum.RunStrategy.Random, node_list})) + job = Scheduler.new_job(run_strategy: {Quantum.RunStrategy.Random, node_list}) assert [node] = NodeList.nodes(job.run_strategy, job) assert Enum.member?(node_list, node) end test "run strategy all" do node_list = [:node1, :node2] - job = Job.new(Scheduler.config(run_strategy: {Quantum.RunStrategy.All, node_list})) + + job = Scheduler.new_job(run_strategy: {Quantum.RunStrategy.All, node_list}) assert [:node1, :node2] == NodeList.nodes(job.run_strategy, job) end end diff --git a/test/quantum_startup_test.exs b/test/quantum_startup_test.exs index 1431b78..54acbb1 100644 --- a/test/quantum_startup_test.exs +++ b/test/quantum_startup_test.exs @@ -10,7 +10,7 @@ defmodule QuantumStartupTest do defmodule Scheduler do @moduledoc false - use Quantum, otp_app: :quantum_startup_test + use Quantum, otp_app: :quantum end @tag :startup @@ -24,17 +24,15 @@ defmodule QuantumStartupTest do {"4 * * * *", fn -> :ok end} ] - Application.put_env(:quantum_startup_test, QuantumStartupTest.Scheduler, jobs: test_jobs) + Application.put_env(:quantum, QuantumStartupTest.Scheduler, jobs: test_jobs) - capture_log(fn -> - {:ok, _pid} = start_supervised(Scheduler) + start_supervised!(Scheduler) - assert Enum.count(QuantumStartupTest.Scheduler.jobs()) == 4 - assert QuantumStartupTest.Scheduler.find_job(:test_job).schedule == ~e[1 * * * *] - assert QuantumStartupTest.Scheduler.find_job(:inactive_job).state == :inactive + assert Enum.count(QuantumStartupTest.Scheduler.jobs()) == 4 + assert QuantumStartupTest.Scheduler.find_job(:test_job).schedule == ~e[1 * * * *] + assert QuantumStartupTest.Scheduler.find_job(:inactive_job).state == :inactive - :ok = stop_supervised(Scheduler) - end) + :ok = stop_supervised(Scheduler) end) end end