Migrate background job processing from Oban to Exq

- Replace Oban dependency with Exq for Redis-based background jobs
- Update PacketCleanupWorker to use Exq's perform/1 signature
- Add CleanupScheduler GenServer for periodic job scheduling
- Configure Exq with Redis connection and queue settings
- Update tests to work with Exq job format
- Maintain 6-hour packet cleanup schedule functionality

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Graham McIntire 2025-07-26 18:39:50 -05:00
parent e00d1bdf47
commit 1f4aaf2a80
No known key found for this signature in database
8 changed files with 166 additions and 34 deletions

View file

@ -31,17 +31,27 @@ config :aprsme, AprsmeWeb.Gettext,
locales: ~w(en es de fr), locales: ~w(en es de fr),
default_locale: "en" default_locale: "en"
# Configure Oban for background jobs # Configure Exq for background jobs
config :aprsme, Oban, config :exq,
repo: Aprsme.Repo, name: Exq,
plugins: [ host: "localhost",
{Oban.Plugins.Pruner, max_age: 60 * 60 * 24 * 7}, port: 6379,
{Oban.Plugins.Cron, password: "",
crontab: [ database: 0,
{"0 */6 * * *", Aprsme.Workers.PacketCleanupWorker} concurrency: :infinite,
]} queues: [
{"default", 10},
{"maintenance", 2}
], ],
queues: [default: 10, maintenance: 2] scheduler_enable: true,
scheduler_poll_timeout: 200,
poll_timeout: 50,
redis_timeout: 5000
# Configure periodic cleanup job
config :aprsme, :cleanup_scheduler,
enabled: true,
interval: 6 * 60 * 60 * 1000 # 6 hours in milliseconds
config :aprsme, config :aprsme,
ecto_repos: [Aprsme.Repo] ecto_repos: [Aprsme.Repo]

View file

@ -27,8 +27,11 @@ config :aprsme, AprsmeWeb.Endpoint,
secret_key_base: "IV9+ENaw9i8xjReRk4sULRvRgsmFVTGQwQGGrf4G+Q/SFMeHBCNWRlPXQ2YvT36R", secret_key_base: "IV9+ENaw9i8xjReRk4sULRvRgsmFVTGQwQGGrf4G+Q/SFMeHBCNWRlPXQ2YvT36R",
server: false server: false
# Disable Oban during tests to prevent background job execution # Disable Exq during tests to prevent background job execution
config :aprsme, Oban, testing: :inline config :exq, mode: :inline
# Disable cleanup scheduler in test environment
config :aprsme, :cleanup_scheduler, enabled: false
# Disable initialize replay delay in test environment # Disable initialize replay delay in test environment
config :aprsme, :initialize_replay_delay, 0 config :aprsme, :initialize_replay_delay, 0

View file

@ -43,8 +43,8 @@ defmodule Aprsme.Application do
# Start a worker by calling: Aprsme.Worker.start_link(arg) # Start a worker by calling: Aprsme.Worker.start_link(arg)
# {Aprsme.Worker, arg} # {Aprsme.Worker, arg}
{Registry, keys: :duplicate, name: Registry.PubSub, partitions: System.schedulers_online()}, {Registry, keys: :duplicate, name: Registry.PubSub, partitions: System.schedulers_online()},
# Start Oban for background jobs # Start cleanup scheduler for periodic packet cleanup
{Oban, :aprsme |> Application.get_env(Oban, []) |> Keyword.put(:queues, default: 10, maintenance: 2)}, Aprsme.CleanupScheduler,
Aprsme.Presence, Aprsme.Presence,
Aprsme.PostgresNotifier, Aprsme.PostgresNotifier,
# Start the packet processing pipeline # Start the packet processing pipeline
@ -54,6 +54,7 @@ defmodule Aprsme.Application do
children = maybe_add_cluster_components(children) children = maybe_add_cluster_components(children)
children = maybe_add_is_supervisor(children, Application.get_env(:aprsme, :env)) children = maybe_add_is_supervisor(children, Application.get_env(:aprsme, :env))
children = maybe_add_aprs_connection(children, Application.get_env(:aprsme, :env)) children = maybe_add_aprs_connection(children, Application.get_env(:aprsme, :env))
children = maybe_add_exq(children)
# See https://hexdocs.pm/elixir/Supervisor.html # See https://hexdocs.pm/elixir/Supervisor.html
# for other strategies and supported options # for other strategies and supported options
@ -181,6 +182,68 @@ defmodule Aprsme.Application do
end end
end end
defp exq_config do
redis_url = System.get_env("REDIS_URL", "redis://localhost:6379")
{Exq,
name: Exq,
host: parse_redis_host(redis_url),
port: parse_redis_port(redis_url),
password: parse_redis_password(redis_url),
database: parse_redis_database(redis_url),
concurrency: :infinite,
queues: [
{"default", 10},
{"maintenance", 2}
],
scheduler_enable: true,
scheduler_poll_timeout: 200,
poll_timeout: 50,
redis_timeout: 5000}
end
defp parse_redis_host(redis_url) do
%URI{host: host} = URI.parse(redis_url)
host || "localhost"
end
defp parse_redis_port(redis_url) do
%URI{port: port} = URI.parse(redis_url)
port || 6379
end
defp parse_redis_password(redis_url) do
case URI.parse(redis_url) do
%URI{userinfo: nil} -> ""
%URI{userinfo: userinfo} ->
case String.split(userinfo, ":") do
[_user, password] -> password
_ -> ""
end
end
end
defp parse_redis_database(redis_url) do
case URI.parse(redis_url) do
%URI{path: nil} -> 0
%URI{path: ""} -> 0
%URI{path: "/" <> db} ->
case Integer.parse(db) do
{num, ""} -> num
_ -> 0
end
end
end
defp maybe_add_exq(children) do
env = Application.get_env(:aprsme, :env)
if env == :test do
children
else
children ++ [exq_config()]
end
end
defp redis_children do defp redis_children do
if System.get_env("REDIS_URL") do if System.get_env("REDIS_URL") do
require Logger require Logger

View file

@ -0,0 +1,57 @@
defmodule Aprsme.CleanupScheduler do
@moduledoc """
GenServer that schedules periodic packet cleanup jobs using Exq.
This scheduler replaces the Oban cron functionality for packet cleanup.
It runs every 6 hours by default and enqueues a cleanup job.
"""
use GenServer
require Logger
def start_link(opts) do
GenServer.start_link(__MODULE__, opts, name: __MODULE__)
end
@impl true
def init(_opts) do
config = Application.get_env(:aprsme, :cleanup_scheduler, [])
enabled = Keyword.get(config, :enabled, true)
interval = Keyword.get(config, :interval, 6 * 60 * 60 * 1000) # 6 hours
if enabled do
Logger.info("Starting packet cleanup scheduler with #{interval}ms interval")
schedule_next_cleanup(interval)
{:ok, %{interval: interval}}
else
Logger.info("Packet cleanup scheduler disabled")
{:ok, %{interval: nil}}
end
end
@impl true
def handle_info(:schedule_cleanup, %{interval: interval} = state) when is_integer(interval) do
Logger.info("Scheduling packet cleanup job")
# Enqueue cleanup job with Exq
case Exq.enqueue(Exq, "maintenance", Aprsme.Workers.PacketCleanupWorker, []) do
{:ok, _job_id} ->
Logger.info("Packet cleanup job scheduled successfully")
{:error, reason} ->
Logger.error("Failed to schedule packet cleanup job: #{inspect(reason)}")
end
schedule_next_cleanup(interval)
{:noreply, state}
end
@impl true
def handle_info(:schedule_cleanup, state) do
# Scheduler is disabled
{:noreply, state}
end
defp schedule_next_cleanup(interval) do
Process.send_after(self(), :schedule_cleanup, interval)
end
end

View file

@ -1,6 +1,6 @@
defmodule Aprsme.Workers.PacketCleanupWorker do defmodule Aprsme.Workers.PacketCleanupWorker do
@moduledoc """ @moduledoc """
Oban worker for cleaning up old APRS packet data. Exq worker for cleaning up old APRS packet data.
This worker is responsible for: This worker is responsible for:
1. Removing packets older than the retention period (1 year by default) 1. Removing packets older than the retention period (1 year by default)
@ -8,7 +8,7 @@ defmodule Aprsme.Workers.PacketCleanupWorker do
3. Logging statistics about cleanup operations 3. Logging statistics about cleanup operations
4. Supporting batch processing for large datasets 4. Supporting batch processing for large datasets
This worker is scheduled to run every 6 hours via Oban's cron feature for more frequent, This worker is scheduled to run every 6 hours via Exq cron feature for more frequent,
smaller cleanup operations to prevent large deletion spikes. smaller cleanup operations to prevent large deletion spikes.
## Functions ## Functions
@ -17,8 +17,6 @@ defmodule Aprsme.Workers.PacketCleanupWorker do
- `cleanup_packets_in_batches/1` - Batch cleanup for large datasets - `cleanup_packets_in_batches/1` - Batch cleanup for large datasets
""" """
use Oban.Worker, queue: :maintenance, max_attempts: 3
# Import modules needed for database operations # Import modules needed for database operations
import Ecto.Query import Ecto.Query
@ -32,9 +30,8 @@ defmodule Aprsme.Workers.PacketCleanupWorker do
# Maximum time to spend on cleanup in milliseconds (5 minutes) # Maximum time to spend on cleanup in milliseconds (5 minutes)
@max_cleanup_time 5 * 60 * 1000 @max_cleanup_time 5 * 60 * 1000
@impl Oban.Worker @spec perform(map()) :: :ok | {:error, String.t()}
@spec perform(Oban.Job.t()) :: :ok | {:error, String.t()} def perform(%{"cleanup_days" => days}) when is_integer(days) do
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") Logger.info("Starting scheduled APRS packet cleanup for packets older than #{days} days")
# Count packets before cleanup for statistics # Count packets before cleanup for statistics
@ -50,8 +47,8 @@ defmodule Aprsme.Workers.PacketCleanupWorker do
:ok :ok
end end
@spec perform(Oban.Job.t()) :: :ok | {:error, String.t()} @spec perform(map()) :: :ok | {:error, String.t()}
def perform(%Oban.Job{args: _args}) do def perform(_args) do
Logger.info("Starting scheduled APRS packet cleanup") Logger.info("Starting scheduled APRS packet cleanup")
# Count packets before cleanup for statistics # Count packets before cleanup for statistics

14
mix.exs
View file

@ -78,7 +78,7 @@ defmodule Aprsme.MixProject do
{:hackney, "~> 1.24"}, {:hackney, "~> 1.24"},
{:jason, "~> 1.4"}, {:jason, "~> 1.4"},
{:libcluster, "~> 3.3"}, {:libcluster, "~> 3.3"},
{:oban, "~> 2.11"}, {:exq, "~> 0.20"},
{:phoenix, "~> 1.8.0-rc.3", override: true}, {:phoenix, "~> 1.8.0-rc.3", override: true},
{:phoenix_ecto, "~> 4.4"}, {:phoenix_ecto, "~> 4.4"},
{:phoenix_html, "~> 4.0"}, {:phoenix_html, "~> 4.0"},
@ -149,12 +149,12 @@ defmodule Aprsme.MixProject do
end end
defp aprs_dep do defp aprs_dep do
{:aprs, path: "vendor/aprs"} # {:aprs, path: "vendor/aprs"}
# if Mix.env() in [:dev] do if Mix.env() in [:dev, :test] do
# {:aprs, path: "vendor/aprs"} {:aprs, github: "aprsme/aprs", branch: "main"}
# else else
# {:aprs, github: "aprsme/aprs", branch: "main"} {:aprs, github: "aprsme/aprs", branch: "main"}
# end end
end end
# Copy Gleam BEAM files to the release # Copy Gleam BEAM files to the release

View file

@ -14,6 +14,7 @@
"ecto_psql_extras": {:hex, :ecto_psql_extras, "0.8.8", "aa02529c97f69aed5722899f5dc6360128735a92dd169f23c5d50b1f7fdede08", [:mix], [{:ecto_sql, "~> 3.7", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:postgrex, "> 0.16.0", [hex: :postgrex, repo: "hexpm", optional: false]}, {:table_rex, "~> 3.1.1 or ~> 4.0", [hex: :table_rex, repo: "hexpm", optional: false]}], "hexpm", "04c63d92b141723ad6fed2e60a4b461ca00b3594d16df47bbc48f1f4534f2c49"}, "ecto_psql_extras": {:hex, :ecto_psql_extras, "0.8.8", "aa02529c97f69aed5722899f5dc6360128735a92dd169f23c5d50b1f7fdede08", [:mix], [{:ecto_sql, "~> 3.7", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:postgrex, "> 0.16.0", [hex: :postgrex, repo: "hexpm", optional: false]}, {:table_rex, "~> 3.1.1 or ~> 4.0", [hex: :table_rex, repo: "hexpm", optional: false]}], "hexpm", "04c63d92b141723ad6fed2e60a4b461ca00b3594d16df47bbc48f1f4534f2c49"},
"ecto_sql": {:hex, :ecto_sql, "3.13.2", "a07d2461d84107b3d037097c822ffdd36ed69d1cf7c0f70e12a3d1decf04e2e1", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.13.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.7", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.19 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "539274ab0ecf1a0078a6a72ef3465629e4d6018a3028095dc90f60a19c371717"}, "ecto_sql": {:hex, :ecto_sql, "3.13.2", "a07d2461d84107b3d037097c822ffdd36ed69d1cf7c0f70e12a3d1decf04e2e1", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.13.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.7", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.19 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "539274ab0ecf1a0078a6a72ef3465629e4d6018a3028095dc90f60a19c371717"},
"elixir_make": {:hex, :elixir_make, "0.9.0", "6484b3cd8c0cee58f09f05ecaf1a140a8c97670671a6a0e7ab4dc326c3109726", [:mix], [], "hexpm", "db23d4fd8b757462ad02f8aa73431a426fe6671c80b200d9710caf3d1dd0ffdb"}, "elixir_make": {:hex, :elixir_make, "0.9.0", "6484b3cd8c0cee58f09f05ecaf1a140a8c97670671a6a0e7ab4dc326c3109726", [:mix], [], "hexpm", "db23d4fd8b757462ad02f8aa73431a426fe6671c80b200d9710caf3d1dd0ffdb"},
"elixir_uuid": {:hex, :elixir_uuid, "1.2.1", "dce506597acb7e6b0daeaff52ff6a9043f5919a4c3315abb4143f0b00378c097", [:mix], [], "hexpm", "f7eba2ea6c3555cea09706492716b0d87397b88946e6380898c2889d68585752"},
"erlex": {:hex, :erlex, "0.2.7", "810e8725f96ab74d17aac676e748627a07bc87eb950d2b83acd29dc047a30595", [:mix], [], "hexpm", "3ed95f79d1a844c3f6bf0cea61e0d5612a42ce56da9c03f01df538685365efb0"}, "erlex": {:hex, :erlex, "0.2.7", "810e8725f96ab74d17aac676e748627a07bc87eb950d2b83acd29dc047a30595", [:mix], [], "hexpm", "3ed95f79d1a844c3f6bf0cea61e0d5612a42ce56da9c03f01df538685365efb0"},
"error_tracker": {:hex, :error_tracker, "0.6.0", "ac37d943b0720faccc26bc3adf39b2b74968b1ee0ae681c2fb57c98c5a10178d", [:mix], [{:ecto, "~> 3.11", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.0", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:ecto_sqlite3, ">= 0.0.0", [hex: :ecto_sqlite3, repo: "hexpm", optional: true]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:myxql, ">= 0.0.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:phoenix_ecto, "~> 4.6", [hex: :phoenix_ecto, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 0.19 or ~> 1.0", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:postgrex, ">= 0.0.0", [hex: :postgrex, repo: "hexpm", optional: true]}], "hexpm", "8b99db5abeb883e7d622daf850c4dda38ce3bfabc4455431212d698df3156c63"}, "error_tracker": {:hex, :error_tracker, "0.6.0", "ac37d943b0720faccc26bc3adf39b2b74968b1ee0ae681c2fb57c98c5a10178d", [:mix], [{:ecto, "~> 3.11", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.0", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:ecto_sqlite3, ">= 0.0.0", [hex: :ecto_sqlite3, repo: "hexpm", optional: true]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:myxql, ">= 0.0.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:phoenix_ecto, "~> 4.6", [hex: :phoenix_ecto, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 0.19 or ~> 1.0", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:postgrex, ">= 0.0.0", [hex: :postgrex, repo: "hexpm", optional: true]}], "hexpm", "8b99db5abeb883e7d622daf850c4dda38ce3bfabc4455431212d698df3156c63"},
"esbuild": {:hex, :esbuild, "0.10.0", "b0aa3388a1c23e727c5a3e7427c932d89ee791746b0081bbe56103e9ef3d291f", [:mix], [{:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "468489cda427b974a7cc9f03ace55368a83e1a7be12fba7e30969af78e5f8c70"}, "esbuild": {:hex, :esbuild, "0.10.0", "b0aa3388a1c23e727c5a3e7427c932d89ee791746b0081bbe56103e9ef3d291f", [:mix], [{:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "468489cda427b974a7cc9f03ace55368a83e1a7be12fba7e30969af78e5f8c70"},
@ -21,6 +22,7 @@
"ex_hash_ring": {:hex, :ex_hash_ring, "6.0.4", "bef9d2d796afbbe25ab5b5a7ed746e06b99c76604f558113c273466d52fa6d6b", [:mix], [], "hexpm", "89adabf31f7d3dfaa36802ce598ce918e9b5b33bae8909ac1a4d052e1e567d18"}, "ex_hash_ring": {:hex, :ex_hash_ring, "6.0.4", "bef9d2d796afbbe25ab5b5a7ed746e06b99c76604f558113c273466d52fa6d6b", [:mix], [], "hexpm", "89adabf31f7d3dfaa36802ce598ce918e9b5b33bae8909ac1a4d052e1e567d18"},
"exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, repo: "hexpm", optional: false]}], "hexpm", "32e95820a97cffea67830e91514a2ad53b888850442d6d395f53a1ac60c82e07"}, "exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, repo: "hexpm", optional: false]}], "hexpm", "32e95820a97cffea67830e91514a2ad53b888850442d6d395f53a1ac60c82e07"},
"expo": {:hex, :expo, "1.1.0", "f7b9ed7fb5745ebe1eeedf3d6f29226c5dd52897ac67c0f8af62a07e661e5c75", [:mix], [], "hexpm", "fbadf93f4700fb44c331362177bdca9eeb8097e8b0ef525c9cc501cb9917c960"}, "expo": {:hex, :expo, "1.1.0", "f7b9ed7fb5745ebe1eeedf3d6f29226c5dd52897ac67c0f8af62a07e661e5c75", [:mix], [], "hexpm", "fbadf93f4700fb44c331362177bdca9eeb8097e8b0ef525c9cc501cb9917c960"},
"exq": {:hex, :exq, "0.20.0", "69996ccfbb2510a08c83692eb930faf0138f2c4d7101700db9f945946570f571", [:mix], [{:elixir_uuid, ">= 1.2.0", [hex: :elixir_uuid, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:poison, ">= 1.2.0 and < 6.0.0", [hex: :poison, repo: "hexpm", optional: true]}, {:redix, ">= 0.9.0", [hex: :redix, repo: "hexpm", optional: false]}], "hexpm", "f9b9c57117e1aa7f23b6b3ab6f8be26e7ca56aa1e7e7ea32413ec4284e350971"},
"exvcr": {:hex, :exvcr, "0.17.1", "3bae83d698a464a48212ad87c8ea4bcfb6bd76d53b937129472764e557616228", [:mix], [{:exjsx, "~> 4.0", [hex: :exjsx, repo: "hexpm", optional: false]}, {:finch, "~> 0.16", [hex: :finch, repo: "hexpm", optional: true]}, {:httpoison, "~> 1.0 or ~> 2.0", [hex: :httpoison, repo: "hexpm", optional: true]}, {:ibrowse, "~> 4.4", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:meck, "~> 1.0", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm", "a39d86980da183011366a878972e0ed43a5441814b701edd2e11360564e7bcab"}, "exvcr": {:hex, :exvcr, "0.17.1", "3bae83d698a464a48212ad87c8ea4bcfb6bd76d53b937129472764e557616228", [:mix], [{:exjsx, "~> 4.0", [hex: :exjsx, repo: "hexpm", optional: false]}, {:finch, "~> 0.16", [hex: :finch, repo: "hexpm", optional: true]}, {:httpoison, "~> 1.0 or ~> 2.0", [hex: :httpoison, repo: "hexpm", optional: true]}, {:ibrowse, "~> 4.4", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:meck, "~> 1.0", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm", "a39d86980da183011366a878972e0ed43a5441814b701edd2e11360564e7bcab"},
"faker": {:hex, :faker, "0.18.0", "943e479319a22ea4e8e39e8e076b81c02827d9302f3d32726c5bf82f430e6e14", [:mix], [], "hexpm", "bfbdd83958d78e2788e99ec9317c4816e651ad05e24cfd1196ce5db5b3e81797"}, "faker": {:hex, :faker, "0.18.0", "943e479319a22ea4e8e39e8e076b81c02827d9302f3d32726c5bf82f430e6e14", [:mix], [], "hexpm", "bfbdd83958d78e2788e99ec9317c4816e651ad05e24cfd1196ce5db5b3e81797"},
"file_system": {:hex, :file_system, "1.1.0", "08d232062284546c6c34426997dd7ef6ec9f8bbd090eb91780283c9016840e8f", [:mix], [], "hexpm", "bfcf81244f416871f2a2e15c1b515287faa5db9c6bcf290222206d120b3d43f6"}, "file_system": {:hex, :file_system, "1.1.0", "08d232062284546c6c34426997dd7ef6ec9f8bbd090eb91780283c9016840e8f", [:mix], [], "hexpm", "bfcf81244f416871f2a2e15c1b515287faa5db9c6bcf290222206d120b3d43f6"},

View file

@ -26,7 +26,7 @@ defmodule Aprsme.Workers.PacketCleanupWorkerTest do
describe "perform/1 with cleanup_days" do describe "perform/1 with cleanup_days" do
test "cleans up packets older than the specified number of days" do test "cleans up packets older than the specified number of days" do
days = 30 days = 30
job = %Oban.Job{args: %{"cleanup_days" => days}} job_args = %{"cleanup_days" => days}
# Create old packets that should be deleted # Create old packets that should be deleted
old_time = DateTime.utc_now() |> DateTime.add(-(days + 1) * 86_400, :second) |> DateTime.truncate(:second) old_time = DateTime.utc_now() |> DateTime.add(-(days + 1) * 86_400, :second) |> DateTime.truncate(:second)
@ -36,7 +36,7 @@ defmodule Aprsme.Workers.PacketCleanupWorkerTest do
recent_time = DateTime.utc_now() |> DateTime.add(-5 * 86_400, :second) |> DateTime.truncate(:second) recent_time = DateTime.utc_now() |> DateTime.add(-5 * 86_400, :second) |> DateTime.truncate(:second)
insert_packets(3, %{received_at: recent_time}) insert_packets(3, %{received_at: recent_time})
assert :ok = PacketCleanupWorker.perform(job) assert :ok = PacketCleanupWorker.perform(job_args)
# Verify only recent packets remain # Verify only recent packets remain
assert Repo.aggregate(Packet, :count, :id) == 3 assert Repo.aggregate(Packet, :count, :id) == 3
@ -45,7 +45,7 @@ defmodule Aprsme.Workers.PacketCleanupWorkerTest do
describe "perform/1 without cleanup_days" do describe "perform/1 without cleanup_days" do
test "cleans up packets using the default retention period" do test "cleans up packets using the default retention period" do
job = %Oban.Job{args: %{}} job_args = %{}
# Create very old packets that should be deleted (older than 365 days) # Create very old packets that should be deleted (older than 365 days)
old_time = DateTime.utc_now() |> DateTime.add(-400 * 86_400, :second) |> DateTime.truncate(:second) old_time = DateTime.utc_now() |> DateTime.add(-400 * 86_400, :second) |> DateTime.truncate(:second)
@ -55,7 +55,7 @@ defmodule Aprsme.Workers.PacketCleanupWorkerTest do
recent_time = DateTime.utc_now() |> DateTime.add(-5 * 86_400, :second) |> DateTime.truncate(:second) recent_time = DateTime.utc_now() |> DateTime.add(-5 * 86_400, :second) |> DateTime.truncate(:second)
insert_packets(3, %{received_at: recent_time}) insert_packets(3, %{received_at: recent_time})
assert :ok = PacketCleanupWorker.perform(job) assert :ok = PacketCleanupWorker.perform(job_args)
# Verify only recent packets remain # Verify only recent packets remain
assert Repo.aggregate(Packet, :count, :id) == 3 assert Repo.aggregate(Packet, :count, :id) == 3