Run Oban and schedule jobs in not booted system

I am trying to use Oban to queue jobs that send emails from a code that is run with eval "MySystem.Tasks.schedule_emails()". I do not have the system booted and trying to start Oban manual.
My code is something like

defmodule MySystem.Tasks do
  def schedule_emails do
     Ecto.Migrator.with_repo(MySystem.Repo, fn repo ->
        Application.ensure_all_started(:oban)
        config = Keyword.put(Application.fetch_env!(:my_system, Oban), :repo, repo)
        Supervisor.start_child(Oban.Registry, {Oban, config})

        do_schedule_emails()
     end)
  end

  defp do_schedule_emails do
    ...
    Oban.insert(SendEmailWorker.new(params))
  end
end

My question is if that is the correct way of starting the Oban.Registry and the Oban application?

The Oban registry is an internal detail and you don’t need to start children in it. Instead, you should use Oban.start_link:

Ecto.Migrator.with_repo(MySystem.Repo, fn repo ->
  Application.ensure_all_started(:oban)

  :my_system
  |> Application.fetch_env!(Oban)
  |> Keyword.put(:repo, repo)
  |> Oban.start_link()

  do_schedule_emails()
end)

Alternatively, if you’re only inserting emails without uniqueness, then you can use Repo.insert instead of Oban.insert and avoid starting Oban altogether.

1 Like