Skip to content

Commit

Permalink
Job Config Options
Browse files Browse the repository at this point in the history
  • Loading branch information
maennchen committed Feb 24, 2022
1 parent 77db89e commit 485aaae
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 35 deletions.
27 changes: 25 additions & 2 deletions lib/quantum.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
39 changes: 18 additions & 21 deletions lib/quantum/job.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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 """
Expand All @@ -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.
Expand Down
7 changes: 4 additions & 3 deletions test/quantum/run_strategy_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -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
16 changes: 7 additions & 9 deletions test/quantum_startup_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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

0 comments on commit 485aaae

Please sign in to comment.