aprs.me/lib/aprsme/application.ex

125 lines
3.8 KiB
Elixir

defmodule Aprsme.Application do
# See https://hexdocs.pm/elixir/Application.html
# for more information on OTP Applications
@moduledoc false
use Application
# Configure Oban for background jobs
@impl true
def start(_type, _args) do
# Run migrations on startup
migrate()
:logger.add_handler(:my_sentry_handler, Sentry.LoggerHandler, %{
config: %{metadata: [:file, :line]}
})
topologies = Application.get_env(:libcluster, :topologies) || []
children = [
# Start the Telemetry supervisor
AprsmeWeb.Telemetry,
# Start the Ecto repository
Aprsme.Repo,
# Start the PubSub system
{Phoenix.PubSub, name: Aprsme.PubSub},
# Start cache systems
%{id: :query_cache, start: {Cachex, :start_link, [:query_cache, [limit: 10_000]]}},
%{id: :device_cache, start: {Cachex, :start_link, [:device_cache, [limit: 5_000]]}},
%{id: :symbol_cache, start: {Cachex, :start_link, [:symbol_cache, [limit: 1_000]]}},
# Start circuit breaker
Aprsme.CircuitBreaker,
# Start the Endpoint (http/https)
AprsmeWeb.Endpoint,
# Start a worker by calling: Aprsme.Worker.start_link(arg)
# {Aprsme.Worker, arg}
{Registry, keys: :duplicate, name: Registry.PubSub, partitions: System.schedulers_online()},
{Cluster.Supervisor, [topologies, [name: Aprsme.ClusterSupervisor]]},
# Start Oban for background jobs
{Oban, :aprsme |> Application.get_env(Oban, []) |> Keyword.put(:queues, default: 10, maintenance: 2)},
Aprsme.Presence,
Aprsme.PostgresNotifier,
# Start the packet processing pipeline
Aprsme.PacketPipelineSupervisor,
# Start the packet pipeline setup
Aprsme.PacketPipelineSetup
]
children = maybe_add_is_supervisor(children, Application.get_env(:aprsme, :env))
children = maybe_add_aprs_connection(children, Application.get_env(:aprsme, :env))
# See https://hexdocs.pm/elixir/Supervisor.html
# for other strategies and supported options
opts = [strategy: :one_for_one, name: Aprsme.Supervisor]
{:ok, sup} = Supervisor.start_link(children, opts)
# Now that the Repo is started, run the refresh in a background task
# Skip in test environment to avoid DBConnection.OwnershipError
env = Application.get_env(:aprsme, :env)
if env != :test do
Task.start(fn -> Aprsme.DeviceIdentification.maybe_refresh_devices() end)
end
{:ok, sup}
end
# Tell Phoenix to update the endpoint configuration
# whenever the application is updated.
@impl true
def config_change(changed, _new, removed) do
AprsmeWeb.Endpoint.config_change(changed, removed)
:ok
end
defp migrate do
auto_migrate = Application.get_env(:aprsme, :auto_migrate, true)
do_migrate(auto_migrate)
# Gettext translations are automatically compiled during Mix compilation
rescue
error ->
require Logger
Logger.error("Failed to run migrations: #{inspect(error)}")
# Don't crash the application, just log the error
:ok
end
defp maybe_add_is_supervisor(children, env) do
disable_connection = Application.get_env(:aprsme, :disable_aprs_connection, false)
if env in [:prod, :dev] and not disable_connection do
children ++ [Aprsme.Is.IsSupervisor]
else
children
end
end
defp maybe_add_aprs_connection(children, _env) do
disable_connection = Application.get_env(:aprsme, :disable_aprs_connection, false)
if disable_connection do
children
else
children ++ [Aprsme.AprsIsConnection]
end
end
defp do_migrate(true) do
require Logger
Logger.info("Running database migrations...")
Aprsme.Release.migrate()
Logger.info("Database migrations completed")
end
defp do_migrate(false) do
require Logger
Logger.info("Automatic migrations disabled")
end
end