Current section

Files

Jump to
quantum lib quantum.ex
Raw

lib/quantum.ex

defmodule Quantum do
@moduledoc """
Contains config functions to aid the rest of the lib
"""
require Logger
alias Quantum.{Job, Normalizer, RunStrategy.Random, Storage.Noop}
@defaults [
global: false,
cron: [],
timeout: 5_000,
schedule: nil,
overlap: true,
timezone: :utc,
run_strategy: {Random, :cluster},
debug_logging: true
]
@doc """
Retrieves only scheduler related configuration.
"""
def scheduler_config(quantum, otp_app, custom) do
config =
@defaults
|> Keyword.merge(Application.get_env(otp_app, quantum, []))
|> Keyword.merge(custom)
|> Keyword.merge(otp_app: otp_app, quantum: quantum)
# Default Job Broadcaster Name
global = Keyword.fetch!(config, :global)
job_broadcaster = cluster_worker_config(Module.concat(quantum, JobBroadcaster), global)
execution_broadcaster =
cluster_worker_config(Module.concat(quantum, ExecutionBroadcaster), global)
executor_supervisor = Module.concat(quantum, ExecutorSupervisor)
task_registry = cluster_worker_config(Module.concat(quantum, TaskRegistry), global)
# Default Task Supervisor Name
cluster_task_supervisor_registry = Module.concat(quantum, ClusterTaskSupervisorRegistry)
task_supervisor = Module.concat(quantum, Task.Supervisor)
config
|> Keyword.put_new(:quantum, quantum)
|> update_in([:schedule], &Normalizer.normalize_schedule/1)
|> Keyword.put_new(:job_broadcaster, job_broadcaster)
|> Keyword.put_new(:execution_broadcaster, execution_broadcaster)
|> Keyword.put_new(:executor_supervisor, executor_supervisor)
|> Keyword.put_new(:task_registry, task_registry)
|> Keyword.put_new(:task_supervisor, task_supervisor)
|> Keyword.put_new(:cluster_task_supervisor_registry, cluster_task_supervisor_registry)
|> Keyword.put_new(:storage, Noop)
end
defp cluster_worker_config(module, false), do: [name: module, restart: :permanent]
defp cluster_worker_config(module, true),
do: [name: {:via, :swarm, module}, restart: :temporary]
@doc """
Retrieves the comprehensive runtime configuration.
"""
def runtime_config(quantum, otp_app, custom) do
config = scheduler_config(quantum, otp_app, custom)
# Load Jobs from Config
jobs =
config
|> Keyword.get(:jobs, [])
|> Enum.map(&Normalizer.normalize(quantum.new_job(config), &1))
|> remove_jobs_with_duplicate_names(quantum)
Keyword.put(config, :jobs, jobs)
end
defp remove_jobs_with_duplicate_names(job_list, quantum) do
job_list
|> Enum.reduce(%{}, fn %Job{name: name} = job, acc ->
if Enum.member?(Map.keys(acc), name) do
Logger.warn(
"Job with name '#{name}' of quantum '#{quantum}' not started due to duplicate job name"
)
acc
else
Map.put_new(acc, name, job)
end
end)
|> Map.values()
end
end