Create Quantum elixir jobs

1.2k Views Asked by At

I want to create a quantum elixir job and control the time it is executed. I started with this:

Quantum.Job.new(task: fn -> IO.puts "Hello!" end)

but it throws this error:

** (KeyError) key :run_strategy not found in: [task: #Function<20.99386804/0 in :erl_eval.expr/5>]
    (elixir) lib/keyword.ex:371: Keyword.fetch!/2
    (quantum) lib/quantum/job.ex:58: Quantum.Job.new/1

I really don't understand the run_strategy setting and it's possible values.

Does somebody knows how to create a quantum job using the struct of Quantum.Job.new or something similar?

NOTE: the cron is already working using this:

config :sopitas, Sopitas.Scheduler,
  jobs: [
    # Every minute
    {"@minutely", {Sopitas.Admin.FixtureController, :update_cron, []}},
    {"@minutely", {Sopitas.Admin.StandingController, :update_cron, []}},
    {"@daily", {Sopitas.Admin.LeagueController, :update_cron, []}},
  ]

but the point is to change the time the cron is executed, that's why I decided to create it using Quantum.Job.new

2

There are 2 best solutions below

0
On

The solution was easier than I thought. The Quantum documentation says:

config :your_app, YourApp.Scheduler, jobs: [
     # Every minute
     {"* * * * ", {Heartbeat, :send, []}},
     # Every 15 minutes
     {"
/15 * * * *", fn -> System.cmd("rm", ["/tmp/tmp_"]) end},
     # Runs on 18, 20, 22, 0, 2, 4, 6:
     {"0 18-6/2 * * *", fn -> :mnesia.backup('/var/backup/mnesia') end},
     # Runs every midnight:
     {"@daily", {Backup, :backup, []}}
]

I changed the tuples by lists, so I can name each job. I can fetch them by their names and change their schedules:

config :sopitas, Sopitas.Scheduler,
  jobs: [
    [name: :redis_cleaning, schedule: "@daily", task: {Sopitas.NotificationController, :clear_redis, []}],
    [name: :fixtures, schedule: "@daily", task: {Sopitas.Admin.FixtureController, :update_cron, []}],
    [name: :standings, schedule: "@daily", task: {Sopitas.Admin.StandingController, :update_cron, []}],
    [name: :leagues, schedule: "@daily", task: {Sopitas.Admin.LeagueController, :update_cron, []}],
    # [name: :example_cron, schedule: "@minutely", task: fn -> IO.puts "Hello!" end],
  ]

I created a function which handles the jobs:

  def change_cron(name, cron_expression) do
    job = Sopitas.Scheduler.find_job(name)
    unless job do
      Quantum.Job.set_schedule(job, Crontab.CronExpression.Parser.parse! cron_expression)
    end
  end

I call that function as follows:

Sopitas.SportsController.change_cron :fixtures, "@daily"
Sopitas.SportsController.change_cron :fixtures, "@minutely"
3
On

The very first sentence in the Quantum.Job doc says:

The struct should never be defined by hand. Use Acme.Scheduler.new_job/0 to create a new job and use the setters mentioned below to mutate the job.

The Quantum.Job itself is a struct with three mandatory keys:

@enforce_keys [:run_strategy, :overlap, :timezone]

If you are still positive you want to violate their guidelines, you should pass these three keywords, like:

Quantum.Job.new(
  task: fn -> IO.puts "Hello!" end,
  run_strategy: %Quantum.RunStrategy.All{nodes: [:one, :two]},
  timezone: "Europe/Zurich",
  overlap: false
)

I would suggest you use one of the examples provided here, though.