Job scheduling

Hello everyone!

I am trying to find right solution for my Phoenix application. I should update data every day by sending requests (3000 requests) to some server.
What should I use:

  1. send_after
  2. Quantum
  3. or something else?

Many thanks!

1 Like

I wrote a blog post about some of the built in features you can use for background jobs.

Here’s another approach I’ve used to run a mix task on a regular interval. See the inline docs for how to use it.

defmodule MyApp.Scheduler do
  @moduledoc """
  Schedules a Mix task to be run at a given interval in milliseconds.

  ## Options

  - `:task`: The name of the Mix task to run.
  - `:args`: A list of arguments to pass to the Mix task's `run/1` function.
  - `:interval`: The time interval in millisconds to rerun the task.

  ## Example

  In a supervisor:

      worker(MyApp.Scheduler, [[[
        task: "contest.pick_winners",
        args: [],
        interval: 60000
      ]]], id: :contest_winners)

  On its own:

      MyApp.Scheduler.start_link([task: "ping", args: [], interval: 3000])
  """

  use GenServer

  require Logger

  def start_link(opts) do
    {:ok, pid} = GenServer.start_link(__MODULE__, opts)
    :timer.apply_interval(opts[:interval], __MODULE__, :perform, [pid])
    {:ok, pid}
  end

  def perform(scheduler) do
    GenServer.cast(scheduler, :perform)
  end

  def handle_cast(:perform, opts) do
    Logger.info(~s{Scheduler running "mix #{opts[:task]}" with args #{inspect(opts[:args])}})
    Mix.Task.run(opts[:task], opts[:args])
    Mix.Task.reenable(opts[:task])
    {:noreply, opts}
  end
end
1 Like

If it is very periodic I’d use Quantum, it is more reliable especially if the system restarts on occasion.

2 Likes

You may find this StackOverflow thread helpful:

1 Like

Thanks! :slight_smile:

If you decide to go the send_after route, I wrote a short article that might help you out. That said, because you want this to run periodically at a specific time, rather than “roughly every N seconds/minutes”, Quantum or some other cron-like solution might be a better way to go.

3 Likes