Adoption
Oban Pro layers enhanced functionality on top of Oban through extensions, plugins, and workers. Those enhancements are all optional and require a little configuration to enable.
This guide will walk you through the minimum configuration changes you should make to start utilizing Pro along with some optional suggestions to hint at what's possible.
1-smartengine
1. SmartEngine
The SmartEngine is the brains behind much of Pro's advanced capabilities and added reliability. It brings global concurrency limits, distributed rate limiting, partitioned limiting, unique bulk job inserts, and precise orphaned job rescuing.
The SmartEngine utilizes centralized producer records in an oban_producers
table to coordinate between nodes with minimal load on the database (and without
any reliance on Distributed Erlang clustering).
To start, create a migration to create an oban_producers table:
$ mix ecto.gen.migration add_oban_producers
Within the migration module:
use Ecto.Migration
defdelegate change, to: Oban.Pro.Migrations.ProducersNext, update your config to use the SmartEngine:
config :my_app, Oban,
+ engine: Oban.Pro.Queue.SmartEngine,
repo: MyApp.Repo
...π‘ Explore Queue Options
Apply global concurrency limits across all nodesβe.g. a genuinely global
limit: 1Throttle queue throughput by rate limiting to a maximum number of jobs within a period of time.
Partition global or rate limits within a queue by worker, args, or args sub-keys.
2-dynamiclifeline
2. DynamicLifeline
The DynamicLifeline) plugin is an
enhancement over the basic Oban.Plugins.Lifeline plugin, which uses producer
records to rescue orphaned jobs, i.e., jobs that are stuck in the executing
state because the node shut down before the job could finish. Producer-based
rescuing is entirely accurate and doesn't suffer from erroneous rescues like
basic time-based rescuing.
Without the DynamicLifeline plugin you may need to manually rescue jobs stuck
in the executing state.
config :my_app, Oban,
engine: Oban.Pro.Queue.SmartEngine,
- plugins: [Oban.Plugins.Lifeline]
+ plugins: [Oban.Pro.Plugins.DynamicLifeline]
...By default, the plugin rescues orphaned jobs 1 minute after the queue shuts down.
π‘ Explore Plugins
Adapt basic cron to DynamicCron to make add, update, and remove cron jobs at runtime.
Swap to the DynamicPruner to customize how long jobs in various states, queues, or from particular workers linger.
Use DynamicQueues to define queues and reconfigure queues at runtime, and have those changes persist between restarts.
3-pro-worker
3. Pro.Worker
The Oban.Pro.Worker is a replacement for Oban.Worker with expanded
capabilities such as encryption, enforced structure, output recording, and
execution hooks.
Upgrade all of your workers to Pro workers by switching out the use module and
replacing perform/1 with process/1:
def MyApp.Worker do
- use Oban.Worker
+ use Oban.Pro.Worker
- @impl Oban.Worker
- def perform(%Job{} = job) do
- # Do stuff with the job
- end
+ @impl Oban.Pro.Worker
+ def process(%Job{} = job) do
+ # Do stuff with the job
+ end
endOnly Pro workers support execution hooks, which are especially helpful as a
reliable alternative to telemetry for error reporting. Once you've modified
existing workers you can define a global error hook (be sure to remove any
existing telemetry backed error hooks):
defmodule MyApp.ErrorHook do
def after_process(state, job) when state in [:discard, :error] do
error = job.unsaved_error
extra = Map.take([:attempt, :id, :args, :max_attempts, :meta, :queue, :worker])
Sentry.capture_exception(error.reason, stacktrace: error.stacktrace, extra: extra)
end
def after_process(_state, _job), do: :ok
end
Oban.Pro.Worker.attach_hook(MyApp.ErrorHook)π‘ Explore Pro Workers
Validate args on insert and atomize them during execution with structured jobs.
Stash a job's return value to retrieve it later manually or as part of a workflow with recorded jobs.
Store all job data at rest with encrypted jobs so that sensitive data can't be seen in the clear.
Process jobs in groups while tracking overall progress with Batch workers.
Compose workers together with arbitrary dependencies between jobs with Workflows.
4-oban-pro-testing
4. Oban.Pro.Testing
Switch from Oban.Testing to Oban.Pro.Testing to more easily test workers,
drain queues reliably, supervise test instances, and make assertions about
enqeueud jobs.
defmodule MyApp.Case do
use ExUnit.CaseTemplate
using do
quote do
- use Oban.Testing, repo: MyApp.Repo
+ use Oban.Pro.Testing, repo: MyApp.Repo
end
end
endContinue with the testing guide for additional setup tips, or skip
straight into the Oban.Pro.Testing docs to explore all of the testing
functions.