πŸ› οΈBackground Tasks and Jobs

Once off background tasks

When you just want to run some code in a background task then you can use PetalPro.BackgroundTask.run/1:

PetalPro.BackgroundTask.run(fn ->
  do_some_time_instensive_stuff()
end)

This can be useful for speeding up responses in a HTTP request or LiveView action - you delegate anything that takes time to a background task (eg sending emails, sending to Slack, creating a log, etc.). Since we want to respond to a user request as soon as possible, you run these other non-essential tasks in a background task and it won't hold up the response.

Background jobs with Oban

A background job is a something you want to run outside of a normal HTTP request/response cycle. Things like sending weekly emails or processing images. We use Oban for this.

A background job is performed by a "worker". Each worker gets its own file. Petal Pro comes with an example worker you can duplicate:

defmodule PetalPro.Workers.ExampleWorker do
  @moduledoc """
  Example of how to do async work with Oban.

  Run with:
  Oban.insert(PetalPro.Workers.ExampleWorker.new(%{}))
  """
  use Oban.Worker, queue: :default
  require Logger

  @impl Oban.Worker
  def perform(%Oban.Job{} = _job) do
    today = Timex.now() |> Timex.to_date()
    Logger.info("ExampleWorker: Today is #{today}")
    :ok
  end
end

You can run this worker by inserting a job into the database:

Oban.insert(PetalPro.Workers.ExampleWorker.new(%{}))

Once in the database, Oban will try running the task and retry it if it fails. You can see any failed jobs by checking the database:

Jobs that have been completed are deleted every 24 hours so your database won't swell over time.

Cron jobs

You can tell your workers to work at certain times with Oban's CRON functionality. See the examples in config.exs:

config :petal_pro, Oban,
  repo: PetalPro.Repo,
  queues: [default: 5],
  plugins: [
    {Oban.Plugins.Pruner, max_age: (3600 * 24)},
    {Oban.Plugins.Cron,
      crontab: [
        {"@daily", PetalPro.Workers.ExampleWorker}
        # {"* * * * *", PetalPro.EveryMinuteWorker},
        # {"0 * * * *", PetalPro.EveryHourWorker},
        # {"0 */6 * * *", PetalPro.EverySixHoursWorker},
        # {"0 0 * * SUN", PetalPro.EverySundayWorker},
        # More examples: https://crontab.guru/examples.html
      ]}
  ]