2018-12-23 20:04:54 +00:00
|
|
|
# Pleroma: A lightweight social networking server
|
2022-02-25 23:11:42 -07:00
|
|
|
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
2018-12-23 20:04:54 +00:00
|
|
|
# SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
|
|
2017-03-17 17:09:58 +01:00
|
|
|
defmodule Pleroma.Application do
|
|
|
|
|
use Application
|
2020-02-11 10:12:57 +03:00
|
|
|
|
|
|
|
|
import Cachex.Spec
|
|
|
|
|
|
|
|
|
|
alias Pleroma.Config
|
|
|
|
|
|
2019-12-09 19:11:54 +07:00
|
|
|
require Logger
|
2017-03-17 17:09:58 +01:00
|
|
|
|
2019-02-01 14:11:23 -03:00
|
|
|
@name Mix.Project.config()[:name]
|
2018-11-20 17:55:03 +01:00
|
|
|
@version Mix.Project.config()[:version]
|
2019-02-01 14:11:23 -03:00
|
|
|
@repository Mix.Project.config()[:source_url]
|
2019-08-14 11:55:17 -04:00
|
|
|
|
2018-11-20 17:55:03 +01:00
|
|
|
def name, do: @name
|
|
|
|
|
def version, do: @version
|
2019-03-05 04:18:43 +01:00
|
|
|
def named_version, do: @name <> " " <> @version
|
2019-02-01 03:55:10 -03:00
|
|
|
def repository, do: @repository
|
2018-11-20 17:55:03 +01:00
|
|
|
|
2019-03-05 04:18:43 +01:00
|
|
|
def user_agent do
|
2020-09-02 15:45:47 +03:00
|
|
|
if Process.whereis(Pleroma.Web.Endpoint) do
|
|
|
|
|
case Config.get([:http, :user_agent], :default) do
|
|
|
|
|
:default ->
|
2021-05-31 15:09:11 -05:00
|
|
|
info = "#{Pleroma.Web.Endpoint.url()} <#{Config.get([:instance, :email], "")}>"
|
2020-09-02 15:45:47 +03:00
|
|
|
named_version() <> "; " <> info
|
|
|
|
|
|
|
|
|
|
custom ->
|
|
|
|
|
custom
|
|
|
|
|
end
|
|
|
|
|
else
|
|
|
|
|
# fallback, if endpoint is not started yet
|
|
|
|
|
"Pleroma Data Loader"
|
2019-11-25 09:53:11 +00:00
|
|
|
end
|
2018-11-23 17:40:45 +01:00
|
|
|
end
|
|
|
|
|
|
2017-03-17 17:09:58 +01:00
|
|
|
# See http://elixir-lang.org/docs/stable/elixir/Application.html
|
|
|
|
|
# for more information on OTP Applications
|
|
|
|
|
def start(_type, _args) do
|
2020-07-14 11:41:30 +03:00
|
|
|
# Scrubbers are compiled at runtime and therefore will cause a conflict
|
|
|
|
|
# every time the application is restarted, so we disable module
|
|
|
|
|
# conflicts at runtime
|
|
|
|
|
Code.compiler_options(ignore_module_conflict: true)
|
2020-07-15 15:26:25 +03:00
|
|
|
Pleroma.Telemetry.Logger.attach()
|
2020-07-09 10:53:51 -05:00
|
|
|
Config.Holder.save_default()
|
2019-12-08 19:42:40 +03:00
|
|
|
Pleroma.HTML.compile_scrubbers()
|
2020-09-06 12:13:26 +03:00
|
|
|
Pleroma.Config.Oban.warn()
|
2020-02-11 10:12:57 +03:00
|
|
|
Config.DeprecationWarnings.warn()
|
2024-05-27 21:26:40 +04:00
|
|
|
|
2024-07-23 09:43:41 -04:00
|
|
|
if Config.get([Pleroma.Web.Plugs.HTTPSecurityPlug, :enable], true) do
|
2024-05-27 21:26:40 +04:00
|
|
|
Pleroma.Web.Plugs.HTTPSecurityPlug.warn_if_disabled()
|
|
|
|
|
end
|
|
|
|
|
|
2025-03-19 10:47:32 -07:00
|
|
|
if Config.get(:env) != :test do
|
2025-02-25 12:20:19 +04:00
|
|
|
Pleroma.ApplicationRequirements.verify!()
|
|
|
|
|
end
|
|
|
|
|
|
2019-12-05 20:18:25 +07:00
|
|
|
load_custom_modules()
|
2020-07-12 17:23:33 +02:00
|
|
|
Pleroma.Docs.JSON.compile()
|
2020-09-10 10:54:57 +03:00
|
|
|
limiters_setup()
|
2019-01-28 12:09:41 +01:00
|
|
|
|
2020-03-12 18:28:54 +03:00
|
|
|
adapter = Application.get_env(:tesla, :adapter)
|
|
|
|
|
|
2021-12-15 15:42:37 -05:00
|
|
|
if match?({Tesla.Adapter.Finch, _}, adapter) do
|
|
|
|
|
Logger.info("Starting Finch")
|
2021-12-15 13:53:09 -05:00
|
|
|
Finch.start_link(name: MyFinch)
|
|
|
|
|
end
|
|
|
|
|
|
2025-05-13 00:01:34 +02:00
|
|
|
# Disable warnings_as_errors at runtime, it breaks Phoenix live reload
|
|
|
|
|
# due to protocol consolidation warnings
|
|
|
|
|
# :warnings_as_errors is deprecated via Code.compiler_options/2 since 1.18
|
2025-06-01 21:25:38 +00:00
|
|
|
if Version.compare(System.version(), "1.18.0") == :lt do
|
|
|
|
|
Code.compiler_options(warnings_as_errors: false)
|
2025-05-13 00:01:34 +02:00
|
|
|
end
|
|
|
|
|
|
2017-03-17 17:09:58 +01:00
|
|
|
# Define workers and child supervisors to be supervised
|
2018-03-30 15:01:53 +02:00
|
|
|
children =
|
|
|
|
|
[
|
2022-11-02 22:49:55 -04:00
|
|
|
Pleroma.PromEx,
|
2024-09-16 00:26:57 -04:00
|
|
|
Pleroma.LDAP,
|
2019-08-14 11:55:17 -04:00
|
|
|
Pleroma.Repo,
|
2020-02-11 10:12:57 +03:00
|
|
|
Config.TransferTask,
|
2019-08-14 11:55:17 -04:00
|
|
|
Pleroma.Emoji,
|
2022-08-19 14:58:57 -04:00
|
|
|
Pleroma.Web.Plugs.RateLimiter.Supervisor,
|
|
|
|
|
{Task.Supervisor, name: Pleroma.TaskSupervisor}
|
2018-03-30 15:01:53 +02:00
|
|
|
] ++
|
2019-08-14 11:55:17 -04:00
|
|
|
cachex_children() ++
|
2024-01-20 19:10:57 -05:00
|
|
|
http_children(adapter) ++
|
2019-01-30 12:38:38 +01:00
|
|
|
[
|
2019-08-14 11:55:17 -04:00
|
|
|
Pleroma.Stats,
|
2019-09-26 18:49:57 +07:00
|
|
|
Pleroma.JobQueueMonitor,
|
2020-06-16 15:11:45 +02:00
|
|
|
{Majic.Pool, [name: Pleroma.MajicPool, pool_size: Config.get([:majic_pool, :size], 2)]},
|
2021-02-22 23:09:41 +03:00
|
|
|
{Oban, Config.get(Oban)},
|
|
|
|
|
Pleroma.Web.Endpoint
|
2019-01-30 12:38:38 +01:00
|
|
|
] ++
|
2024-01-20 18:22:49 -05:00
|
|
|
task_children() ++
|
2024-01-20 18:51:20 -05:00
|
|
|
streamer_registry() ++
|
2024-01-20 18:47:25 -05:00
|
|
|
background_migrators() ++
|
2020-08-03 18:41:49 -05:00
|
|
|
shout_child(shout_enabled?()) ++
|
2024-05-25 14:20:47 -04:00
|
|
|
[Pleroma.Gopher.Server] ++
|
|
|
|
|
[Pleroma.Search.Healthcheck]
|
2017-03-17 17:09:58 +01:00
|
|
|
|
|
|
|
|
# See http://elixir-lang.org/docs/stable/elixir/Supervisor.html
|
|
|
|
|
# for other strategies and supported options
|
2022-07-14 13:35:33 +02:00
|
|
|
# If we have a lot of caches, default max_restarts can cause test
|
|
|
|
|
# resets to fail.
|
|
|
|
|
# Go for the default 3 unless we're in test
|
2024-01-20 18:14:27 -05:00
|
|
|
max_restarts = Application.get_env(:pleroma, __MODULE__)[:max_restarts]
|
2022-07-14 13:35:33 +02:00
|
|
|
|
|
|
|
|
opts = [strategy: :one_for_one, name: Pleroma.Supervisor, max_restarts: max_restarts]
|
2024-03-18 15:42:15 -04:00
|
|
|
Supervisor.start_link(children, opts)
|
2017-03-17 17:09:58 +01:00
|
|
|
end
|
2018-02-01 19:23:26 +02:00
|
|
|
|
2019-12-05 20:29:17 +07:00
|
|
|
def load_custom_modules do
|
2020-02-11 10:12:57 +03:00
|
|
|
dir = Config.get([:modules, :runtime_dir])
|
2019-12-05 20:18:25 +07:00
|
|
|
|
|
|
|
|
if dir && File.exists?(dir) do
|
|
|
|
|
dir
|
2019-12-09 18:23:07 +07:00
|
|
|
|> Pleroma.Utils.compile_dir()
|
2019-12-05 20:18:25 +07:00
|
|
|
|> case do
|
|
|
|
|
{:error, _errors, _warnings} ->
|
|
|
|
|
raise "Invalid custom modules"
|
|
|
|
|
|
|
|
|
|
{:ok, modules, _warnings} ->
|
2024-01-20 18:22:49 -05:00
|
|
|
if Application.get_env(:pleroma, __MODULE__)[:load_custom_modules] do
|
2019-12-06 17:05:09 +07:00
|
|
|
Enum.each(modules, fn mod ->
|
2019-12-09 19:11:54 +07:00
|
|
|
Logger.info("Custom module loaded: #{inspect(mod)}")
|
2019-12-06 17:05:09 +07:00
|
|
|
end)
|
|
|
|
|
end
|
2019-12-05 20:18:25 +07:00
|
|
|
|
|
|
|
|
:ok
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2019-08-14 11:55:17 -04:00
|
|
|
defp cachex_children do
|
|
|
|
|
[
|
|
|
|
|
build_cachex("used_captcha", ttl_interval: seconds_valid_interval()),
|
|
|
|
|
build_cachex("user", default_ttl: 25_000, ttl_interval: 1000, limit: 2500),
|
|
|
|
|
build_cachex("object", default_ttl: 25_000, ttl_interval: 1000, limit: 2500),
|
|
|
|
|
build_cachex("rich_media", default_ttl: :timer.minutes(120), limit: 5000),
|
|
|
|
|
build_cachex("scrubber", limit: 2500),
|
2022-06-09 11:39:51 -04:00
|
|
|
build_cachex("scrubber_management", limit: 2500),
|
2019-09-09 18:53:08 +00:00
|
|
|
build_cachex("idempotency", expiration: idempotency_expiration(), limit: 2500),
|
2019-08-12 13:13:01 +03:00
|
|
|
build_cachex("web_resp", limit: 2500),
|
2019-10-01 20:00:27 +00:00
|
|
|
build_cachex("emoji_packs", expiration: emoji_packs_expiration(), limit: 10),
|
2020-06-14 21:02:57 +03:00
|
|
|
build_cachex("failed_proxy_url", limit: 2500),
|
2024-03-08 10:32:15 -05:00
|
|
|
build_cachex("failed_media_helper_url", default_ttl: :timer.minutes(15), limit: 2_500),
|
2020-10-31 05:50:48 +03:00
|
|
|
build_cachex("banned_urls", default_ttl: :timer.hours(24 * 30), limit: 5_000),
|
|
|
|
|
build_cachex("chat_message_id_idempotency_key",
|
|
|
|
|
expiration: chat_message_id_idempotency_key_expiration(),
|
|
|
|
|
limit: 500_000
|
2022-12-29 19:42:14 +00:00
|
|
|
),
|
2023-08-24 00:37:39 +02:00
|
|
|
build_cachex("rel_me", limit: 2500),
|
2024-06-12 17:13:23 +02:00
|
|
|
build_cachex("host_meta", default_ttl: :timer.minutes(120), limit: 5_000),
|
2022-10-30 18:47:41 +01:00
|
|
|
build_cachex("translations", default_ttl: :timer.hours(24), limit: 5_000)
|
2019-08-14 11:55:17 -04:00
|
|
|
]
|
|
|
|
|
end
|
2018-11-19 20:58:12 +01:00
|
|
|
|
2019-08-12 13:13:01 +03:00
|
|
|
defp emoji_packs_expiration,
|
|
|
|
|
do: expiration(default: :timer.seconds(5 * 60), interval: :timer.seconds(60))
|
|
|
|
|
|
2019-08-14 11:55:17 -04:00
|
|
|
defp idempotency_expiration,
|
2019-08-14 14:01:11 -04:00
|
|
|
do: expiration(default: :timer.seconds(6 * 60 * 60), interval: :timer.seconds(60))
|
2019-08-14 11:55:17 -04:00
|
|
|
|
2020-10-31 05:50:48 +03:00
|
|
|
defp chat_message_id_idempotency_key_expiration,
|
|
|
|
|
do: expiration(default: :timer.minutes(2), interval: :timer.seconds(60))
|
|
|
|
|
|
2019-08-14 11:55:17 -04:00
|
|
|
defp seconds_valid_interval,
|
2020-02-11 10:12:57 +03:00
|
|
|
do: :timer.seconds(Config.get!([Pleroma.Captcha, :seconds_valid]))
|
2019-08-14 11:55:17 -04:00
|
|
|
|
2020-07-03 19:18:08 +03:00
|
|
|
@spec build_cachex(String.t(), keyword()) :: map()
|
|
|
|
|
def build_cachex(type, opts),
|
2019-08-14 14:01:11 -04:00
|
|
|
do: %{
|
|
|
|
|
id: String.to_atom("cachex_" <> type),
|
|
|
|
|
start: {Cachex, :start_link, [String.to_atom(type <> "_cache"), opts]},
|
|
|
|
|
type: :worker
|
|
|
|
|
}
|
2019-08-14 11:55:17 -04:00
|
|
|
|
2020-08-03 18:41:49 -05:00
|
|
|
defp shout_enabled?, do: Config.get([:shout, :enabled])
|
2019-08-14 11:55:17 -04:00
|
|
|
|
2024-01-20 19:39:13 -05:00
|
|
|
defp streamer_registry do
|
2024-01-20 18:51:20 -05:00
|
|
|
if Application.get_env(:pleroma, __MODULE__)[:streamer_registry] do
|
|
|
|
|
[
|
|
|
|
|
{Registry,
|
|
|
|
|
[
|
|
|
|
|
name: Pleroma.Web.Streamer.registry(),
|
|
|
|
|
keys: :duplicate,
|
|
|
|
|
partitions: System.schedulers_online()
|
|
|
|
|
]}
|
|
|
|
|
]
|
|
|
|
|
else
|
|
|
|
|
[]
|
|
|
|
|
end
|
2021-03-12 12:18:11 +03:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
defp background_migrators do
|
2024-01-20 18:47:25 -05:00
|
|
|
if Application.get_env(:pleroma, __MODULE__)[:background_migrators] do
|
|
|
|
|
[
|
|
|
|
|
Pleroma.Migrators.HashtagsTableMigrator,
|
|
|
|
|
Pleroma.Migrators.ContextObjectsDeletionMigrator
|
|
|
|
|
]
|
|
|
|
|
else
|
|
|
|
|
[]
|
|
|
|
|
end
|
2018-02-01 19:23:26 +02:00
|
|
|
end
|
2019-01-30 12:38:38 +01:00
|
|
|
|
2020-08-03 18:41:49 -05:00
|
|
|
defp shout_child(true) do
|
2020-10-07 13:28:39 -05:00
|
|
|
[
|
2020-08-03 18:34:58 -05:00
|
|
|
Pleroma.Web.ShoutChannel.ShoutChannelState,
|
2020-10-07 13:28:39 -05:00
|
|
|
{Phoenix.PubSub, [name: Pleroma.PubSub, adapter: Phoenix.PubSub.PG2]}
|
|
|
|
|
]
|
2019-08-14 11:55:17 -04:00
|
|
|
end
|
|
|
|
|
|
2020-08-03 18:41:49 -05:00
|
|
|
defp shout_child(_), do: []
|
2019-08-14 11:55:17 -04:00
|
|
|
|
2024-01-20 19:39:13 -05:00
|
|
|
defp task_children do
|
2024-01-20 18:22:49 -05:00
|
|
|
children = [
|
2019-09-17 14:44:52 +00:00
|
|
|
%{
|
|
|
|
|
id: :web_push_init,
|
|
|
|
|
start: {Task, :start_link, [&Pleroma.Web.Push.init/0]},
|
|
|
|
|
restart: :temporary
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
|
2024-01-20 18:22:49 -05:00
|
|
|
if Application.get_env(:pleroma, __MODULE__)[:internal_fetch] do
|
|
|
|
|
children ++
|
|
|
|
|
[
|
|
|
|
|
%{
|
|
|
|
|
id: :internal_fetch_init,
|
|
|
|
|
start: {Task, :start_link, [&Pleroma.Web.ActivityPub.InternalFetchActor.init/0]},
|
|
|
|
|
restart: :temporary
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
else
|
|
|
|
|
children
|
|
|
|
|
end
|
2019-09-17 14:44:52 +00:00
|
|
|
end
|
2020-02-11 10:12:57 +03:00
|
|
|
|
|
|
|
|
# start hackney and gun pools in tests
|
2024-01-20 19:10:57 -05:00
|
|
|
defp http_children(adapter) do
|
|
|
|
|
if Application.get_env(:pleroma, __MODULE__)[:test_http_pools] do
|
|
|
|
|
http_children_hackney() ++ http_children_gun()
|
|
|
|
|
else
|
|
|
|
|
cond do
|
|
|
|
|
match?(Tesla.Adapter.Hackney, adapter) -> http_children_hackney()
|
|
|
|
|
match?(Tesla.Adapter.Gun, adapter) -> http_children_gun()
|
|
|
|
|
true -> []
|
|
|
|
|
end
|
|
|
|
|
end
|
2020-02-11 10:12:57 +03:00
|
|
|
end
|
|
|
|
|
|
2024-01-20 19:39:13 -05:00
|
|
|
defp http_children_hackney do
|
2020-02-11 10:12:57 +03:00
|
|
|
pools = [:federation, :media]
|
|
|
|
|
|
|
|
|
|
pools =
|
|
|
|
|
if Config.get([Pleroma.Upload, :proxy_remote]) do
|
|
|
|
|
[:upload | pools]
|
|
|
|
|
else
|
|
|
|
|
pools
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
for pool <- pools do
|
|
|
|
|
options = Config.get([:hackney_pools, pool])
|
|
|
|
|
:hackney_pool.child_spec(pool, options)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2024-01-20 19:39:13 -05:00
|
|
|
defp http_children_gun do
|
2020-05-17 22:16:02 +03:00
|
|
|
Pleroma.Gun.ConnectionPool.children() ++
|
|
|
|
|
[{Task, &Pleroma.HTTP.AdapterHelper.Gun.limiter_setup/0}]
|
2020-05-06 01:51:10 +03:00
|
|
|
end
|
2020-03-03 12:19:29 +03:00
|
|
|
|
2020-11-20 11:37:01 +03:00
|
|
|
@spec limiters_setup() :: :ok
|
2020-09-10 10:54:57 +03:00
|
|
|
def limiters_setup do
|
2021-01-09 18:52:40 +03:00
|
|
|
config = Config.get(ConcurrentLimiter, [])
|
|
|
|
|
|
2021-08-15 21:53:04 +03:00
|
|
|
[
|
|
|
|
|
Pleroma.Search
|
|
|
|
|
]
|
2021-01-09 18:52:40 +03:00
|
|
|
|> Enum.each(fn module ->
|
|
|
|
|
mod_config = Keyword.get(config, module, [])
|
|
|
|
|
|
|
|
|
|
max_running = Keyword.get(mod_config, :max_running, 5)
|
|
|
|
|
max_waiting = Keyword.get(mod_config, :max_waiting, 5)
|
|
|
|
|
|
|
|
|
|
ConcurrentLimiter.new(module, max_running, max_waiting)
|
|
|
|
|
end)
|
2020-09-10 10:54:57 +03:00
|
|
|
end
|
2017-03-17 17:09:58 +01:00
|
|
|
end
|