🚅 Streamlined Workflows
Workflows now use automatic scheduling to run workflow jobs in order, without any polling or
snoozing. Jobs with upstream dependencies are automatically marked as on_hold
and scheduled far
into the future. After the upstream dependency executes they're made available to run, with
consideration for retries, cancellations, and discards.
-
An optimized, debounced query system uses up to 10x fewer queries to execute slower workflows.
-
Queue concurrency limits don't impact workflow execution, and even complex workflows can quickly run in parallel with
global_limit: 1
and zero snoozing. -
Cancelled, deleted, and discarded dependencies are still handled according to their respective
ignore_*
policies.
All of the previous workflow "tuning" options like waiting_limit
and waiting_snooze
are gone,
as they're not needed to optimize workflow execution. Finally, older "in flight" workflows will
still run with the legacy polling mechanism to ensure backwards compatibility.
⏲️ Job Execution Deadlines
Jobs that shouldn't run after some period of time can be marked with a deadline
. After the
deadline has passed the job will be pre-emptively cancelled on its next run, or optionally
during its next run if desired.
defmodule DeadlinedWorker do
use Oban.Pro.Worker, deadline: {1, :hour}
@impl true
def process(%Job{args: args}) do
# If this doesn't run within an hour, it's cancelled
end
end
Deadlines may be set at runtime as well:
DeadlinedWorker.new(args, deadline: {30, :minutes})
In either case, the deadline is always relative and computed at runtime. That also allows the deadline to consider scheduling—a job scheduled to run 1 hour from now with a 1 hour deadline will expire 2 hours in the future.
🧙 Automatic Crontab Syncing
Synchronizing persisted entries manually required two deploys: one to flag it with deleted: true
and another to clean up the entry entirely. That extra step isn't ideal for applications that
don't insert or delete jobs at runtime.
To delete entries that are no longer listed in the crontab automatically set the sync_mode
option to :automatic
:
[
sync_mode: :automatic,
crontab: [
{"0 * * * *", MyApp.BasicJob},
{"0 0 * * *", MyApp.OtherJob}
]
]
To remove unwanted entries, simply delete them from the crontab:
crontab: [
{"0 * * * *", MyApp.BasicJob},
- {"0 0 * * *", MyApp.OtherJob}
]
With :automatic
sync, the entry for MyApp.OtherJob
will be deleted on the next deployment.
❤️🩹🌟 Upgrading to v1.4
Changes to
DynamicCron
require a migration to add the newinsertions
column. You must re-run theOban.Pro.Migrations.DynamicCron
migration when upgrading.defmodule MyApp.Repo.Migrations.UpdateObanCron do use Ecto.Migration defdelegate change, to: Oban.Pro.Migrations.DynamicCron end