Packages
oban
2.11.2
2.23.0
2.22.1
2.22.0
2.21.1
2.21.0
2.20.3
2.20.2
2.20.1
2.20.0
2.19.4
2.19.3
2.19.2
2.19.1
2.19.0
2.18.3
2.18.2
2.18.1
2.18.0
2.17.12
2.17.11
2.17.10
2.17.9
2.17.8
2.17.7
2.17.6
2.17.5
2.17.4
2.17.3
2.17.2
2.17.1
2.17.0
2.16.3
2.16.2
2.16.1
2.16.0
2.15.4
2.15.3
2.15.2
2.15.1
2.15.0
2.14.2
2.14.1
2.14.0
2.13.6
2.13.5
2.13.4
2.13.3
2.13.2
2.13.1
2.13.0
2.12.1
2.12.0
2.11.3
2.11.2
2.11.1
2.11.0
2.10.1
2.10.0
retired
2.9.2
2.9.1
2.9.0
2.8.0
2.7.2
2.7.1
2.7.0
2.6.1
2.6.0
2.5.0
2.4.3
2.4.2
2.4.1
2.4.0
2.3.4
2.3.3
2.3.2
2.3.1
2.3.0
2.2.0
2.1.0
2.0.0
2.0.0-rc.3
2.0.0-rc.2
2.0.0-rc.1
2.0.0-rc.0
1.2.0
1.1.0
1.0.0
1.0.0-rc.2
1.0.0-rc.1
0.12.1
0.12.0
0.11.1
0.11.0
0.10.1
0.10.0
0.9.0
0.8.1
0.8.0
0.7.1
0.7.0
0.6.0
0.5.0
0.4.0
0.3.0
0.2.0
0.1.0
Robust job processing, backed by modern PostgreSQL, SQLite3, and MySQL.
Current section
Files
Jump to
Current section
Files
lib/oban/plugins/pruner.ex
defmodule Oban.Plugins.Pruner do
@moduledoc """
Periodically delete completed, cancelled and discarded jobs based on age.
## Using the Plugin
The following example demonstrates using the plugin without any configuration, which will prune
jobs older than the default of 60 seconds:
config :my_app, Oban,
plugins: [Oban.Plugins.Pruner],
...
Override the default options to prune jobs after 5 minutes:
config :my_app, Oban,
plugins: [{Oban.Plugins.Pruner, max_age: 300}],
...
> #### 🌟 DynamicPruner {: .info}
>
> This plugin treats all jobs the same and only retains by time. To retain by length or
> provide custom rules for specific queues, workers and job states see the `DynamicPruner` plugin
> in [Oban Pro](dynamic_pruner.html).
## Options
* `:limit` — the maximum number of jobs to prune at one time. The default is 10,000 to prevent
request timeouts. Applications that steadily generate more than 10k jobs a minute should increase
this value.
* `:max_age` — the number of seconds after which a job may be pruned. Defaults to 60s.
## Instrumenting with Telemetry
The `Oban.Plugins.Pruner` plugin adds the following metadata to the `[:oban, :plugin, :stop]` event:
* `:pruned_count` - the number of jobs that were pruned from the database
"""
use GenServer
import Ecto.Query, only: [join: 5, limit: 2, or_where: 3, select: 2]
alias Oban.{Config, Job, Peer, Repo}
@type option ::
{:conf, Config.t()}
| {:name, GenServer.name()}
| {:limit, pos_integer()}
| {:max_age, pos_integer()}
defmodule State do
@moduledoc false
defstruct [
:conf,
:name,
:timer,
max_age: 60,
interval: :timer.seconds(30),
limit: 10_000
]
end
@doc false
@spec start_link([option()]) :: GenServer.on_start()
def start_link(opts) do
GenServer.start_link(__MODULE__, opts, name: opts[:name])
end
@impl GenServer
def init(opts) do
Process.flag(:trap_exit, true)
state =
State
|> struct!(opts)
|> schedule_prune()
{:ok, state}
end
@impl GenServer
def terminate(_reason, state) do
if is_reference(state.timer), do: Process.cancel_timer(state.timer)
:ok
end
@impl GenServer
def handle_info(:prune, %State{} = state) do
meta = %{conf: state.conf, plugin: __MODULE__}
:telemetry.span([:oban, :plugin], meta, fn ->
case check_leadership_and_delete_jobs(state) do
{:ok, {pruned_count, _}} when is_integer(pruned_count) ->
{:ok, Map.put(meta, :pruned_count, pruned_count)}
error ->
{:error, Map.put(meta, :error, error)}
end
end)
{:noreply, schedule_prune(state)}
end
# Scheduling
defp check_leadership_and_delete_jobs(state) do
if Peer.leader?(state.conf) do
Repo.transaction(state.conf, fn ->
delete_jobs(state.conf, state.max_age, state.limit)
end)
else
{:ok, {0, []}}
end
end
defp schedule_prune(state) do
%{state | timer: Process.send_after(self(), :prune, state.interval)}
end
# Query
defp delete_jobs(conf, seconds, limit) do
time = DateTime.add(DateTime.utc_now(), -seconds)
subquery =
Job
|> or_where([j], j.state == "completed" and j.attempted_at < ^time)
|> or_where([j], j.state == "cancelled" and j.cancelled_at < ^time)
|> or_where([j], j.state == "discarded" and j.discarded_at < ^time)
|> select([:id])
|> limit(^limit)
Repo.delete_all(
conf,
join(Job, :inner, [j], x in subquery(subquery), on: j.id == x.id)
)
end
end