defmodule GitGud.Federation.Workers.Retention do
@moduledoc """
Periodic pruner for federation audit data.
Three independently configurable retention windows:
config :git_gud, GitGud.Federation.Workers.Retention,
inbox_deliveries_days: 90,
outbound_deliveries_days: 30,
remote_activities_days: 365
Any value of `nil` (or absence of the key) disables pruning for that
bucket. Local-generated activities (`is_local: true`) are *never*
pruned automatically — they're the audit trail for what we
published.
Schedule via Oban Cron, e.g.:
config :git_gud, Oban,
plugins: [
{Oban.Plugins.Cron, crontab: [
{"@daily", GitGud.Federation.Workers.Retention}
]}
]
"""
use Oban.Worker, queue: :default, max_attempts: 3
import Ecto.Query, warn: false
alias GitGud.Federation.Activity
alias GitGud.Federation.InboxDelivery
alias GitGud.Federation.OutboundDelivery
alias GitGud.Repo
@impl Oban.Worker
def perform(_job) do
opts = Application.get_env(:git_gud, __MODULE__, [])
prune_table(InboxDelivery, Keyword.get(opts, :inbox_deliveries_days))
prune_table(OutboundDelivery, Keyword.get(opts, :outbound_deliveries_days))
prune_remote_activities(Keyword.get(opts, :remote_activities_days))
:ok
end
defp prune_table(_schema, nil), do: 0
defp prune_table(_schema, n) when not is_integer(n), do: 0
defp prune_table(schema, days) when is_integer(days) and days > 0 do
cutoff = DateTime.utc_now() |> DateTime.add(-days * 86_400, :second)
{count, _} =
Repo.delete_all(from r in schema, where: r.inserted_at < ^cutoff)
count
end
defp prune_remote_activities(nil), do: 0
defp prune_remote_activities(n) when not is_integer(n), do: 0
defp prune_remote_activities(days) when is_integer(days) and days > 0 do
cutoff = DateTime.utc_now() |> DateTime.add(-days * 86_400, :second)
{count, _} =
Repo.delete_all(
from a in Activity,
where: a.is_local == false and a.inserted_at < ^cutoff
)
count
end
@doc """
Run all prunes immediately (for tests + manual ops via
`mix gitgud.federation.prune`).
"""
def run_now do
perform(%Oban.Job{args: %{}})
end
end
2.2 KiB · text
5af55d9