Bumps vendored Oban Pro from 1.6.13 to 1.7.0, which transitively bumps oban core to 2.22.1 (requires migrations v14) and db_connection to 2.10.0. - mix.exs constraint: ~> 1.6 → ~> 1.7 - vendor/oban_pro/ replaced with v1.7.0 hex package - migration 20260430142200: Oban core v12 → v14 (must run first) - migration 20260430142241: Oban Pro 1.7.0 schema additions Also corrects a pre-existing constraint name in AgentAssignment that was left stale by the equipment→devices rename migration (20260117190134). The unique index is named agent_assignments_device_id_index, but the schema's unique_constraint/3 still pointed at the old equipment_id name, causing the test suite to surface Ecto.ConstraintError instead of a changeset error. Required to get the suite green for this upgrade.
6.7 KiB
Plugins
Available Plugins
DynamicCron: Runtime-configurable cron scheduling with cluster-wide coordinationDynamicLifeline: Rescues orphaned jobs, repairs stuck workflows/chainsDynamicPrioritizer: Automatically increases priority of waiting jobsDynamicPruner: Flexible job retention with per-queue/worker rulesDynamicQueues: Persists queue configuration across restartsDynamicScaler: Auto-scales cloud infrastructure based on queue depth
DynamicCron
Runtime-configurable cron with cluster-wide coordination. Unlike standard Oban cron, DynamicCron supports runtime updates, guaranteed scheduling, and automatic sync.
Configuration
{Oban.Pro.Plugins.DynamicCron,
timezone: "Etc/UTC",
sync_mode: :automatic,
crontab: [
{"*/5 * * * *", MyApp.Workers.FrequentWorker},
{"0 0 * * *", MyApp.Workers.DailyWorker, guaranteed: true},
{"0 9 * * MON", MyApp.Workers.WeeklyWorker, timezone: "America/New_York"},
{"@reboot", MyApp.Workers.StartupWorker}
]}
Options
timezone— default timezone for all entries (defaults to"Etc/UTC")sync_mode—:automaticsyncs crontab entries to the database on startup, removing stale entries;:manualrequires explicitinsert/1anddelete/1callsguaranteed— per-entry option that ensures missed jobs are inserted when the system comes back online (use for critical scheduled tasks)
Runtime Management
alias Oban.Pro.Plugins.DynamicCron
# Insert or update entries at runtime
DynamicCron.insert({"0 * * * *", MyApp.HourlyWorker})
# Delete an entry
DynamicCron.delete(MyApp.HourlyWorker)
# Get an entry's details
DynamicCron.get(MyApp.HourlyWorker)
# List all entries
DynamicCron.all()
DynamicLifeline
Rescues orphaned jobs and repairs stuck workflows and chains. Essential for production systems where nodes may crash or restart unexpectedly.
Configuration
{Oban.Pro.Plugins.DynamicLifeline, retry_discarded: false}
Options
retry_discarded— whether to retry discarded workflow/chain jobs when dependencies complete
Do not change the rescue_interval option. If you see it configured, remove it—the default is
carefully tuned and changing it causes problems.
What It Rescues
- Orphaned jobs — jobs stuck in
executingstate after a node crash - Stuck workflows — workflows blocked by completed dependencies that weren't properly tracked
- Stuck chains — chains that stopped progressing due to missed completion signals
- Partition backfill — repopulates rate limit and global limit partitions after restarts
DynamicPrioritizer
Automatically increases priority of jobs that have been waiting too long. Prevents starvation of low-priority jobs in busy systems.
Configuration
{Oban.Pro.Plugins.DynamicPrioritizer,
prioritizers: [
rate: [queue: :default, rate: 1, period: to_timeout(second: 30)],
once: [queue: :media, threshold: to_timeout(minute: 5), boost: 1]
]}
Strategies
rate— continuously boost priority at a fixed rate while waitingonce— boost priority once after a threshold wait time
Options
queue— target queue (required)rate— priority boost per period (forratestrategy)period— how often to apply the boost (forratestrategy)threshold— wait time before boosting (foroncestrategy)boost— how much to increase priority (foroncestrategy, default: 1)
DynamicPruner
Flexible job retention with per-queue and per-worker rules. More powerful than the standard Oban pruner with fine-grained control over what gets deleted and when.
Configuration
{Oban.Pro.Plugins.DynamicPruner,
mode: {:max_age, {7, :days}},
queue_overrides: [
logs: {:max_age, {1, :day}},
critical: {:max_age, {30, :days}}
],
worker_overrides: [
MyApp.AuditWorker: {:max_age, {90, :days}},
MyApp.TempWorker: {:max_age, {1, :hour}}
]}
Modes
{:max_age, {count, unit}}— delete jobs older than the specified age{:max_length, count}— keep only the most recent N jobs
Options
mode— default retention rule for all jobsqueue_overrides— per-queue retention rulesworker_overrides— per-worker retention rules (takes precedence over queue rules)state— which job states to prune (default:[:completed, :cancelled, :discarded])
DynamicQueues
Persists queue configuration to the database for runtime management. Queues survive restarts and can be modified without redeploying.
Configuration
{Oban.Pro.Plugins.DynamicQueues,
sync_mode: :automatic,
queues: [
default: 10,
mailers: [local_limit: 20, rate_limit: [allowed: 100, period: {1, :minute}]],
exports: [local_limit: 5, only: {:node, :=~, "worker"}]
]}
Options
sync_mode—:automaticsyncs queue config to database on startup;:manualrequires explicit API callsqueues— initial queue definitions (same format as standard Oban queues)only— restrict queue to matching nodes using{:node, pattern}or{:sys_env, key, pattern}; supports operators:==,:!=,:=~for pattern matching
Runtime Management
alias Oban.Pro.Plugins.DynamicQueues
# Add or update a queue
DynamicQueues.insert(:reports, local_limit: 5)
# Pause a queue
DynamicQueues.pause(:reports)
# Resume a queue
DynamicQueues.resume(:reports)
# Scale a queue
DynamicQueues.scale(:reports, local_limit: 20)
# Delete a queue
DynamicQueues.delete(:reports)
# List all queues
DynamicQueues.all()
DynamicScaler
Auto-scales cloud infrastructure based on queue depth and throughput. Scales nodes horizontally to optimize processing during high traffic and save costs during quiet periods.
Configuration
{Oban.Pro.Plugins.DynamicScaler,
scalers: [
range: 1..5,
cloud: MyApp.Cloud
]}
Options
cloud— module implementing theOban.Pro.Cloudbehaviour (required)range— min..max nodes to scale between (required)cooldown— minimum time between scaling events (default: 120 seconds)queues—:allor list of queues to monitor (default::all)step—:noneor max nodes to scale at once (default::none)
Features
- Predictive scaling — calculates optimal scale based on recent trends, not just current depth
- Multi-cloud — implement the
Cloudbehaviour for your platform (AWS, Fly, Kubernetes, etc.) - Thrashing prevention — cooldown period prevents rapid scale up/down cycles
Cloud Behaviour
Implement Oban.Pro.Cloud for your platform:
defmodule MyApp.Cloud do
@behaviour Oban.Pro.Cloud
@impl true
def init(opts), do: opts
@impl true
def current(_opts), do: {:ok, current_node_count()}
@impl true
def scale(count, _opts), do: scale_to(count)
end