Files
Beam/lib/forum/application.ex
2026-06-10 11:51:56 -05:00

73 lines
2.1 KiB
Elixir

# lib/forum/application.ex
defmodule Forum.Application do
use Application
@impl true
def start(_type, _args) do
db_config = Application.fetch_env!(:forum, Forum.DB)
server_config = Application.fetch_env!(:forum, :server)
children =
[
{Postgrex, [name: Forum.DB] ++ db_config},
# Unique process names for forms, networks, public sites, and HTTP servers.
{Registry, keys: :unique, name: Forum.ProcessRegistry},
# WebSocket clients subscribe here for live forms.html updates.
{Registry, keys: :duplicate, name: Forum.FormsSubscriberRegistry},
Forum.LogStore,
Forum.Networks,
Forum.PublicSiteSupervisor,
# Parses forms.html and supervises one QuickBEAM runtime per
# <forms-> child element. Also serves Forum.Forms.html/0.
Forum.Forms,
# Re-parses forms.html whenever the file changes on disk.
Forum.Forms.Watcher,
# Main HTTP + WebSocket server.
http_server_child(:main, Forum.Router, server_config[:port])
] ++ network_site_servers(server_config)
with {:ok, sup} <- Supervisor.start_link(children, strategy: :one_for_one, name: Forum.Supervisor) do
# DynamicSupervisor can't start children from its own init/1, so
# we kick off the initial parse + spawn here.
Forum.Forms.reload()
Forum.Networks.start_networks()
Forum.PublicSiteSupervisor.start_networks()
{:ok, sup}
end
end
defp network_site_servers(server_config) do
base_port = Keyword.get(server_config, :network_port_base, 4001)
Forum.Networks.network_slugs()
|> Enum.with_index()
|> Enum.map(fn {network, index} ->
http_server_child(
{:network, network},
{Forum.PublicSiteRouter, network: network},
base_port + index
)
end)
end
defp http_server_child(key, plug, port) do
Supervisor.child_spec(
{Bandit,
plug: plug,
port: port,
thousand_island_options: [
supervisor_options: [
name: {:via, Registry, {Forum.ProcessRegistry, {:http_server, key}}}
]
]},
id: {:http_server, key, port}
)
end
end