Convert the packets table to a time-partitioned table with daily partitions (PARTITION BY RANGE on received_at). This replaces the expensive CTE-based batch DELETE cleanup with instant DROP TABLE partition drops — no dead tuples, no WAL pressure, no VACUUM needed. - Add PartitionManager GenServer to create/drop daily partitions - Simplify PacketCleanupWorker to delegate to PartitionManager - Replace gridsquare/geocalc deps with local Maidenhead module - Remove gettext_pseudolocalize dependency - Fix Decimal comparison in packet consumer test
67 lines
2.1 KiB
Elixir
67 lines
2.1 KiB
Elixir
defmodule Aprsme.Workers.PacketCleanupWorker do
|
|
@moduledoc """
|
|
Worker for cleaning up old APRS packet data.
|
|
|
|
Delegates to `PartitionManager.drop_old_partitions/1` which drops entire
|
|
daily partitions past the retention period — instant, no dead tuples, no VACUUM.
|
|
|
|
Also cleans up old `bad_packets` records via standard DELETE.
|
|
"""
|
|
|
|
import Ecto.Query
|
|
|
|
alias Aprsme.BadPacket
|
|
alias Aprsme.PartitionManager
|
|
alias Aprsme.Repo
|
|
|
|
require Logger
|
|
|
|
@spec perform(map()) :: :ok | {:error, String.t()}
|
|
def perform(%{"cleanup_days" => days}) when is_integer(days) and days > 0 do
|
|
Logger.info("Starting scheduled APRS packet cleanup for packets older than #{days} days")
|
|
|
|
{:ok, dropped} = PartitionManager.drop_old_partitions(days)
|
|
|
|
Logger.info("APRS packet cleanup complete: dropped #{length(dropped)} partition(s) older than #{days} days")
|
|
|
|
:ok
|
|
rescue
|
|
error ->
|
|
Logger.error("Packet cleanup failed: #{inspect(error)}\n#{inspect(__STACKTRACE__)}")
|
|
{:error, "Cleanup failed: #{inspect(error)}"}
|
|
end
|
|
|
|
@spec perform(map()) :: :ok | {:error, String.t()}
|
|
def perform(_args) do
|
|
Logger.info("Starting scheduled APRS packet cleanup")
|
|
|
|
retention_days = Application.get_env(:aprsme, :packet_retention_days, 7)
|
|
|
|
{:ok, dropped} = PartitionManager.drop_old_partitions(retention_days)
|
|
bad_packet_count = cleanup_old_bad_packets()
|
|
|
|
Logger.info(
|
|
"APRS packet cleanup complete: dropped #{length(dropped)} partition(s) and removed #{bad_packet_count} bad packets older than #{retention_days} days"
|
|
)
|
|
|
|
:ok
|
|
rescue
|
|
error ->
|
|
Logger.error("Packet cleanup failed: #{inspect(error)}\n#{inspect(__STACKTRACE__)}")
|
|
{:error, "Cleanup failed: #{inspect(error)}"}
|
|
end
|
|
|
|
defp cleanup_old_bad_packets do
|
|
retention_days = Application.get_env(:aprsme, :packet_retention_days, 7)
|
|
cutoff_time = DateTime.add(DateTime.utc_now(), -retention_days * 86_400, :second)
|
|
|
|
{deleted_count, _} =
|
|
Repo.delete_all(from(b in BadPacket, where: b.attempted_at < ^cutoff_time))
|
|
|
|
deleted_count
|
|
rescue
|
|
error ->
|
|
Logger.error("Failed to clean up bad packets: #{inspect(error)}")
|
|
0
|
|
end
|
|
end
|