fix: remove Exq dependency and Redis job queue
- Remove Exq dependency from mix.exs and application config - Remove all Exq configuration from config files (config.exs, dev.exs, runtime.exs, test.exs) - Update CleanupScheduler to run cleanup tasks directly using Task.start instead of queuing jobs - Update PacketCleanupWorker documentation to remove Exq references - Cleanup functionality preserved but now runs in supervised Tasks instead of job queue This resolves the Redis connection error on startup by eliminating the dependency on external job queues. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
cc4578653f
commit
26d93e36c7
7 changed files with 16 additions and 91 deletions
|
|
@ -120,20 +120,6 @@ config :esbuild,
|
||||||
cd: Path.expand("../assets", __DIR__)
|
cd: Path.expand("../assets", __DIR__)
|
||||||
]
|
]
|
||||||
|
|
||||||
# Configure Exq for background jobs
|
|
||||||
# Redis connection settings are configured in runtime.exs
|
|
||||||
config :exq,
|
|
||||||
name: Exq,
|
|
||||||
concurrency: :infinite,
|
|
||||||
queues: [
|
|
||||||
{"default", 10},
|
|
||||||
{"maintenance", 2}
|
|
||||||
],
|
|
||||||
scheduler_enable: true,
|
|
||||||
scheduler_poll_timeout: 200,
|
|
||||||
poll_timeout: 50,
|
|
||||||
redis_timeout: 5000
|
|
||||||
|
|
||||||
config :gettext, :plural_forms, GettextPseudolocalize.Plural
|
config :gettext, :plural_forms, GettextPseudolocalize.Plural
|
||||||
|
|
||||||
# Configures Elixir's Logger
|
# Configures Elixir's Logger
|
||||||
|
|
|
||||||
|
|
@ -74,11 +74,6 @@ config :aprsme, AprsmeWeb.Endpoint,
|
||||||
# Run `mix help phx.gen.cert` for more information.
|
# Run `mix help phx.gen.cert` for more information.
|
||||||
config :aprsme, dev_routes: true
|
config :aprsme, dev_routes: true
|
||||||
|
|
||||||
# Disable Exq in development (no Redis required)
|
|
||||||
# Jobs that would normally run in the background will be skipped
|
|
||||||
config :exq,
|
|
||||||
start_on_application: false
|
|
||||||
|
|
||||||
# Mailer configuration for development
|
# Mailer configuration for development
|
||||||
# Using Swoosh.Adapters.Local from config.exs which stores emails locally
|
# Using Swoosh.Adapters.Local from config.exs which stores emails locally
|
||||||
# Access sent emails at http://localhost:4000/dev/mailbox
|
# Access sent emails at http://localhost:4000/dev/mailbox
|
||||||
|
|
|
||||||
|
|
@ -49,55 +49,6 @@ if config_env() == :prod do
|
||||||
# Configure clustering based on environment
|
# Configure clustering based on environment
|
||||||
cluster_enabled = System.get_env("CLUSTER_ENABLED", "false") == "true"
|
cluster_enabled = System.get_env("CLUSTER_ENABLED", "false") == "true"
|
||||||
|
|
||||||
# Configure Exq with Redis connection from environment
|
|
||||||
redis_url = System.get_env("REDIS_URL", "redis://localhost:6379")
|
|
||||||
redis_uri = URI.parse(redis_url)
|
|
||||||
redis_host = redis_uri.host || "localhost"
|
|
||||||
redis_port = redis_uri.port || 6379
|
|
||||||
|
|
||||||
redis_password =
|
|
||||||
case redis_uri.userinfo do
|
|
||||||
nil ->
|
|
||||||
""
|
|
||||||
|
|
||||||
userinfo ->
|
|
||||||
case String.split(userinfo, ":") do
|
|
||||||
[_, password] -> password
|
|
||||||
_ -> ""
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Extract database from path if present
|
|
||||||
redis_database =
|
|
||||||
try do
|
|
||||||
case redis_uri.path do
|
|
||||||
nil ->
|
|
||||||
0
|
|
||||||
|
|
||||||
"/" ->
|
|
||||||
0
|
|
||||||
|
|
||||||
path ->
|
|
||||||
path |> String.trim_leading("/") |> String.to_integer()
|
|
||||||
end
|
|
||||||
rescue
|
|
||||||
_ -> 0
|
|
||||||
end
|
|
||||||
|
|
||||||
exq_config = [
|
|
||||||
host: redis_host,
|
|
||||||
port: redis_port,
|
|
||||||
database: redis_database
|
|
||||||
]
|
|
||||||
|
|
||||||
# Only add password if it's not empty
|
|
||||||
exq_config =
|
|
||||||
if redis_password != "" and redis_password != nil do
|
|
||||||
Keyword.put(exq_config, :password, redis_password)
|
|
||||||
else
|
|
||||||
exq_config
|
|
||||||
end
|
|
||||||
|
|
||||||
# Parse SSL configuration from environment
|
# Parse SSL configuration from environment
|
||||||
ssl_enabled = System.get_env("DATABASE_SSL", "false") == "true"
|
ssl_enabled = System.get_env("DATABASE_SSL", "false") == "true"
|
||||||
ssl_verify = System.get_env("DATABASE_SSL_VERIFY", "true") == "true"
|
ssl_verify = System.get_env("DATABASE_SSL_VERIFY", "true") == "true"
|
||||||
|
|
@ -196,8 +147,6 @@ if config_env() == :prod do
|
||||||
aprs_is_password: System.get_env("APRS_PASSCODE"),
|
aprs_is_password: System.get_env("APRS_PASSCODE"),
|
||||||
env: :prod
|
env: :prod
|
||||||
|
|
||||||
config :exq, exq_config
|
|
||||||
|
|
||||||
# Configure Hammer for production environment
|
# Configure Hammer for production environment
|
||||||
config :hammer,
|
config :hammer,
|
||||||
backend: {Hammer.Backend.ETS, [expiry_ms: 60_000 * 60 * 4, cleanup_interval_ms: 60_000 * 10]}
|
backend: {Hammer.Backend.ETS, [expiry_ms: 60_000 * 60 * 4, cleanup_interval_ms: 60_000 * 10]}
|
||||||
|
|
|
||||||
|
|
@ -59,11 +59,6 @@ config :bcrypt_elixir, :log_rounds, 1
|
||||||
# Disable ErrorTracker in test environment to avoid database ownership issues
|
# Disable ErrorTracker in test environment to avoid database ownership issues
|
||||||
config :error_tracker, enabled: false
|
config :error_tracker, enabled: false
|
||||||
|
|
||||||
# Disable Exq during tests to prevent background job execution
|
|
||||||
config :exq,
|
|
||||||
start_on_application: false,
|
|
||||||
mode: :inline
|
|
||||||
|
|
||||||
# Configure ExVCR
|
# Configure ExVCR
|
||||||
config :exvcr,
|
config :exvcr,
|
||||||
vcr_cassette_library_dir: "test/fixtures/vcr_cassettes",
|
vcr_cassette_library_dir: "test/fixtures/vcr_cassettes",
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
defmodule Aprsme.CleanupScheduler do
|
defmodule Aprsme.CleanupScheduler do
|
||||||
@moduledoc """
|
@moduledoc """
|
||||||
GenServer that schedules periodic packet cleanup jobs using Exq.
|
GenServer that schedules periodic packet cleanup tasks.
|
||||||
|
|
||||||
This scheduler replaces the Oban cron functionality for packet cleanup.
|
This scheduler runs cleanup tasks directly every 6 hours by default
|
||||||
It runs every 6 hours by default and enqueues a cleanup job.
|
without requiring external job queues.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
use GenServer
|
use GenServer
|
||||||
|
|
@ -33,16 +33,17 @@ defmodule Aprsme.CleanupScheduler do
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def handle_info(:schedule_cleanup, %{interval: interval} = state) when is_integer(interval) do
|
def handle_info(:schedule_cleanup, %{interval: interval} = state) when is_integer(interval) do
|
||||||
Logger.info("Scheduling packet cleanup job")
|
Logger.info("Running packet cleanup task")
|
||||||
|
|
||||||
# Enqueue cleanup job with Exq
|
# Run cleanup directly in a supervised task
|
||||||
case Exq.enqueue(Exq, "maintenance", Aprsme.Workers.PacketCleanupWorker, []) do
|
Task.start(fn ->
|
||||||
{:ok, _job_id} ->
|
try do
|
||||||
Logger.info("Packet cleanup job scheduled successfully")
|
Aprsme.Workers.PacketCleanupWorker.perform(%{})
|
||||||
|
rescue
|
||||||
{:error, reason} ->
|
error ->
|
||||||
Logger.error("Failed to schedule packet cleanup job: #{inspect(reason)}")
|
Logger.error("Packet cleanup task failed: #{inspect(error)}")
|
||||||
end
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
schedule_next_cleanup(interval)
|
schedule_next_cleanup(interval)
|
||||||
{:noreply, state}
|
{:noreply, state}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
defmodule Aprsme.Workers.PacketCleanupWorker do
|
defmodule Aprsme.Workers.PacketCleanupWorker do
|
||||||
@moduledoc """
|
@moduledoc """
|
||||||
Exq worker for cleaning up old APRS packet data.
|
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 Exq cron feature for more frequent,
|
This worker is scheduled to run every 6 hours for more frequent,
|
||||||
smaller cleanup operations to prevent large deletion spikes.
|
smaller cleanup operations to prevent large deletion spikes.
|
||||||
|
|
||||||
## Functions
|
## Functions
|
||||||
|
|
|
||||||
3
mix.exs
3
mix.exs
|
|
@ -43,7 +43,7 @@ defmodule Aprsme.MixProject do
|
||||||
def application do
|
def application do
|
||||||
[
|
[
|
||||||
mod: {Aprsme.Application, []},
|
mod: {Aprsme.Application, []},
|
||||||
extra_applications: [:hackney, :logger, :runtime_tools, :os_mon, :exq]
|
extra_applications: [:hackney, :logger, :runtime_tools, :os_mon]
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -69,7 +69,6 @@ defmodule Aprsme.MixProject do
|
||||||
{:gettext, "~> 0.26.2"},
|
{:gettext, "~> 0.26.2"},
|
||||||
{:jason, "~> 1.4"},
|
{:jason, "~> 1.4"},
|
||||||
{:libcluster, "~> 3.3"},
|
{:libcluster, "~> 3.3"},
|
||||||
{: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.3.0"},
|
{:phoenix_html, "~> 4.3.0"},
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue