change packet retention to a year

This commit is contained in:
Graham McIntire 2025-06-16 08:25:53 -05:00
parent b6260a950f
commit 2b3cc3f75e
No known key found for this signature in database
6 changed files with 84 additions and 99 deletions

View file

@ -38,25 +38,6 @@ defmodule Aprs.Is do
last_second_timestamp: System.system_time(:second)
}
# Set up ets tables
# with {:ok, :aprs} <- :ets.file2tab(:erlang.binary_to_list("priv/aprs.ets")),
# {:ok, :aprs_messages} <- :ets.file2tab(:erlang.binary_to_list("priv/aprs_messages.ets")) do
# else
# {:error, _reason} ->
# Logger.debug("Ets files not found. Creating new ETS tables.")
# # Create new ETS tables
# :ets.new(:aprs, [:set, :protected, :named_table])
# :ets.new(:aprs_messages, [:bag, :protected, :named_table])
# # Write them to file here in case genserver is brutally terminated
# :ets.tab2file(:aprs, :erlang.binary_to_list("priv/aprs.ets"))
# :ets.tab2file(:aprs_messages, :erlang.binary_to_list("priv/aprs_messages.ets"))
# _ ->
# Logger.error("Unable to set up ETS tables for message storage.")
# end
with {:ok, socket} <- connect_to_aprs_is(server, port),
:ok <- send_login_string(socket, aprs_user_id, aprs_passcode, default_filter) do
timer = create_timer(@aprs_timeout)

View file

@ -270,11 +270,11 @@ defmodule Aprs.Packets do
Configure packet retention policy.
Packets are retained based on these rules:
- Default retention is 30 days (configurable via :packet_retention_days)
- Default retention is 365 days (1 year) (configurable via :packet_retention_days)
- Returns the number of packets deleted
"""
def clean_old_packets do
retention_days = Application.get_env(:aprs, :packet_retention_days, 30)
retention_days = Application.get_env(:aprs, :packet_retention_days, 365)
cutoff_time = DateTime.add(DateTime.utc_now(), -retention_days * 86_400, :second)
{deleted_count, _} = Repo.delete_all(from(p in Packet, where: p.received_at < ^cutoff_time))
@ -282,6 +282,26 @@ defmodule Aprs.Packets do
deleted_count
end
@doc """
Clean packets older than a specific number of days.
This function allows for more granular cleanup operations by specifying
the exact age threshold for packet deletion.
## Parameters
- `days` - Number of days to retain packets (packets older than this will be deleted)
## Returns
- Number of packets deleted
"""
def clean_packets_older_than(days) when is_integer(days) and days > 0 do
cutoff_time = DateTime.add(DateTime.utc_now(), -days * 86_400, :second)
{deleted_count, _} = Repo.delete_all(from(p in Packet, where: p.received_at < ^cutoff_time))
deleted_count
end
# Helper to convert various types to float
defp to_float(value) when is_float(value), do: value
defp to_float(value) when is_integer(value), do: value * 1.0

View file

@ -36,7 +36,7 @@ defmodule Aprs.Passcode do
hash =
Enum.reduce(0..div(length(chars) - 1, 2), hash, fn i, acc ->
current_char = Enum.at(chars, i * 2)
next_char = if i * 2 + 1 < length(chars), do: Enum.at(chars, i * 2 + 1), else: nil
next_char = if i * 2 + 1 < length(chars), do: Enum.at(chars, i * 2 + 1)
step1 = Bitwise.bxor(acc, Bitwise.bsl(current_char, 8))
step2 =

View file

@ -1,68 +0,0 @@
defmodule Aprs.Scheduled.PacketCleanup do
@moduledoc """
Scheduled task to clean up old APRS packet data.
This module is responsible for:
1. Removing packets older than the retention period (30 days by default)
2. Logging statistics about the cleanup operation
"""
use GenServer
alias Aprs.Packets
require Logger
# Run cleanup once per day
@cleanup_interval_ms 24 * 60 * 60 * 1000
def start_link(_opts) do
GenServer.start_link(__MODULE__, %{})
end
@impl true
def init(state) do
# Schedule first cleanup
schedule_cleanup()
{:ok, state}
end
@impl true
def handle_info(:cleanup, state) do
# Run the cleanup
_cleanup_count = perform_cleanup()
# Schedule next cleanup
schedule_cleanup()
{:noreply, state}
end
defp perform_cleanup do
Logger.info("Starting scheduled APRS packet cleanup")
# Count packets before cleanup for statistics
_total_before = count_total_packets()
# Perform the cleanup
deleted_count = Packets.clean_old_packets()
# Log results
retention_days = Application.get_env(:aprs, :packet_retention_days, 30)
Logger.info("APRS packet cleanup complete: removed #{deleted_count} packets older than #{retention_days} days")
# Return deleted count
deleted_count
end
defp count_total_packets do
# Import modules needed for database operations
Aprs.Repo.aggregate(Aprs.Packet, :count, :id)
end
defp schedule_cleanup do
# Schedule next cleanup
Process.send_after(self(), :cleanup, @cleanup_interval_ms)
end
end

View file

@ -3,9 +3,16 @@ defmodule Aprs.Workers.PacketCleanupWorker do
Oban worker for cleaning up old APRS packet data.
This worker is responsible for:
1. Removing packets older than the retention period (30 days by default)
2. Removing old packets from the displayed map (older than 1 hour)
3. Logging statistics about the cleanup operation
1. Removing packets older than the retention period (1 year by default)
2. Providing granular cleanup with custom age parameters
3. Logging statistics about cleanup operations
## Functions
- `perform/1` - Standard cleanup using configured retention period
- `cleanup_packets_older_than/1` - Cleanup packets older than specified days
- `schedule_cleanup/0` - Schedule standard cleanup job
- `schedule_cleanup_for_age/1` - Schedule cleanup with custom age parameter
- `schedule_daily_cleanup/0` - Schedule daily cleanup at midnight UTC
"""
use Oban.Worker, queue: :maintenance, max_attempts: 3
@ -19,17 +26,33 @@ defmodule Aprs.Workers.PacketCleanupWorker do
require Logger
@impl Oban.Worker
def perform(%Oban.Job{args: %{"cleanup_days" => days}}) when is_integer(days) do
Logger.info("Starting scheduled APRS packet cleanup for packets older than #{days} days")
# Count packets before cleanup for statistics
_total_before = count_total_packets()
# Perform the cleanup of old packets with custom age
deleted_count = Packets.clean_packets_older_than(days)
# Log results
Logger.info("APRS packet cleanup complete: removed #{deleted_count} packets older than #{days} days")
# Return success
:ok
end
def perform(%Oban.Job{args: _args}) do
Logger.info("Starting scheduled APRS packet cleanup")
# Count packets before cleanup for statistics
_total_before = count_total_packets()
# Perform the cleanup of old packets (older than 30 days)
# Perform the cleanup of old packets (older than 1 year by default)
deleted_count = cleanup_old_packets()
# Log results
retention_days = Application.get_env(:aprs, :packet_retention_days, 30)
retention_days = Application.get_env(:aprs, :packet_retention_days, 365)
Logger.info("APRS packet cleanup complete: removed #{deleted_count} packets older than #{retention_days} days")
# Return success
@ -43,6 +66,13 @@ defmodule Aprs.Workers.PacketCleanupWorker do
|> Oban.insert()
end
# Schedule cleanup with custom age parameter
def schedule_cleanup_for_age(days) when is_integer(days) and days > 0 do
%{"cleanup_days" => days}
|> Oban.Job.new(worker: __MODULE__, queue: :maintenance)
|> Oban.insert()
end
# Schedule this job to run daily at midnight UTC
def schedule_daily_cleanup do
# Calculate when the next midnight UTC is
@ -74,4 +104,25 @@ defmodule Aprs.Workers.PacketCleanupWorker do
# Use the existing function from Packets context
Packets.clean_old_packets()
end
@doc """
Perform cleanup of packets older than a specific number of days.
This function provides more granular control over packet cleanup operations.
## Parameters
- `days` - Number of days to retain packets (packets older than this will be deleted)
## Returns
- Number of packets deleted
"""
def cleanup_packets_older_than(days) when is_integer(days) and days > 0 do
Logger.info("Starting APRS packet cleanup for packets older than #{days} days")
deleted_count = Packets.clean_packets_older_than(days)
Logger.info("APRS packet cleanup complete: removed #{deleted_count} packets older than #{days} days")
deleted_count
end
end

View file

@ -1,22 +1,23 @@
defmodule Aprs.PasscodeTest do
use ExUnit.Case
doctest Aprs.Passcode
describe "generate/1" do
test "generates correct passcode for W5ISP" do
assert Aprs.Passcode.generate("W5ISP") == 15748
assert Aprs.Passcode.generate("W5ISP") == 15_748
end
test "handles callsigns with SSIDs" do
assert Aprs.Passcode.generate("W5ISP-1") == 15748
assert Aprs.Passcode.generate("W5ISP-1") == 15_748
end
test "handles lowercase callsigns" do
assert Aprs.Passcode.generate("w5isp") == 15748
assert Aprs.Passcode.generate("w5isp") == 15_748
end
test "handles long callsigns" do
assert Aprs.Passcode.generate("W5ISP-LONG") == 15748
assert Aprs.Passcode.generate("W5ISP-LONG") == 15_748
end
end
end