X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=lib%2Fpleroma%2Fapplication.ex;h=0273972bed96c425c75a15dd1d461a52cb285057;hb=a079ec3a3cdfd42d2cbd51c7698c2c87828e5778;hp=308d8cffa661ad3cf1ab8cf3dfb3845fcda1a8d4;hpb=39a78998d0a729323406497332f9402301994811;p=akkoma
diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex
index 308d8cffa..0273972be 100644
--- a/lib/pleroma/application.ex
+++ b/lib/pleroma/application.ex
@@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors
+# Copyright © 2017-2021 Pleroma Authors
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Application do
@@ -14,7 +14,7 @@ defmodule Pleroma.Application do
@name Mix.Project.config()[:name]
@version Mix.Project.config()[:version]
@repository Mix.Project.config()[:source_url]
- @env Mix.env()
+ @mix_env Mix.env()
def name, do: @name
def version, do: @version
@@ -22,50 +22,40 @@ defmodule Pleroma.Application do
def repository, do: @repository
def user_agent do
- case Config.get([:http, :user_agent], :default) do
- :default ->
- info = "#{Pleroma.Web.base_url()} <#{Config.get([:instance, :email], "")}>"
- named_version() <> "; " <> info
-
- custom ->
- custom
+ if Process.whereis(Pleroma.Web.Endpoint) do
+ case Config.get([:http, :user_agent], :default) do
+ :default ->
+ info = "#{Pleroma.Web.Endpoint.url()} <#{Config.get([:instance, :email], "")}>"
+ named_version() <> "; " <> info
+
+ custom ->
+ custom
+ end
+ else
+ # fallback, if endpoint is not started yet
+ "Pleroma Data Loader"
end
end
# See http://elixir-lang.org/docs/stable/elixir/Application.html
# for more information on OTP Applications
def start(_type, _args) do
- Pleroma.Config.Holder.save_default()
+ # 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)
+ # Disable warnings_as_errors at runtime, it breaks Phoenix live reload
+ # due to protocol consolidation warnings
+ Code.compiler_options(warnings_as_errors: false)
+ Config.Holder.save_default()
Pleroma.HTML.compile_scrubbers()
+ Pleroma.Config.Oban.warn()
Config.DeprecationWarnings.warn()
- Pleroma.Plugs.HTTPSecurityPlug.warn_if_disabled()
- Pleroma.Repo.check_migrations_applied!()
- setup_instrumenters()
+ Pleroma.Web.Plugs.HTTPSecurityPlug.warn_if_disabled()
+ Pleroma.ApplicationRequirements.verify!()
load_custom_modules()
-
- adapter = Application.get_env(:tesla, :adapter)
-
- if adapter == Tesla.Adapter.Gun do
- if version = Pleroma.OTPVersion.version() do
- [major, minor] =
- version
- |> String.split(".")
- |> Enum.map(&String.to_integer/1)
- |> Enum.take(2)
-
- if (major == 22 and minor < 2) or major < 22 do
- raise "
- !!!OTP VERSION WARNING!!!
- You are using gun adapter with OTP version #{version}, which doesn't support correct handling of unordered certificates chains.
- "
- end
- else
- raise "
- !!!OTP VERSION WARNING!!!
- To support correct handling of unordered certificates chains - OTP version must be > 22.2.
- "
- end
- end
+ Pleroma.Docs.JSON.compile()
+ limiters_setup()
# Define workers and child supervisors to be supervised
children =
@@ -73,27 +63,63 @@ defmodule Pleroma.Application do
Pleroma.Repo,
Config.TransferTask,
Pleroma.Emoji,
- Pleroma.Plugs.RateLimiter.Supervisor
+ Pleroma.Web.Plugs.RateLimiter.Supervisor,
+ {Task.Supervisor, name: Pleroma.TaskSupervisor}
] ++
cachex_children() ++
- http_children(adapter, @env) ++
+ http_children() ++
[
Pleroma.Stats,
Pleroma.JobQueueMonitor,
- {Oban, Config.get(Oban)}
- ] ++
- task_children(@env) ++
- streamer_child(@env) ++
- chat_child(@env, chat_enabled?()) ++
- [
+ {Majic.Pool, [name: Pleroma.MajicPool, pool_size: Config.get([:majic_pool, :size], 2)]},
+ {Oban, Config.get(Oban)},
Pleroma.Web.Endpoint,
- Pleroma.Gopher.Server
- ]
+ Pleroma.Web.Telemetry
+ ] ++
+ elasticsearch_children() ++
+ task_children(@mix_env) ++
+ dont_run_in_test(@mix_env)
# See http://elixir-lang.org/docs/stable/elixir/Supervisor.html
# for other strategies and supported options
- opts = [strategy: :one_for_one, name: Pleroma.Supervisor]
- Supervisor.start_link(children, opts)
+ # 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
+ max_restarts =
+ if @mix_env == :test do
+ 100
+ else
+ 3
+ end
+
+ opts = [strategy: :one_for_one, name: Pleroma.Supervisor, max_restarts: max_restarts]
+
+ with {:ok, data} <- Supervisor.start_link(children, opts) do
+ set_postgres_server_version()
+ {:ok, data}
+ else
+ e ->
+ Logger.error("Failed to start!")
+ Logger.error("#{inspect(e)}")
+ e
+ end
+ end
+
+ defp set_postgres_server_version do
+ version =
+ with %{rows: [[version]]} <- Ecto.Adapters.SQL.query!(Pleroma.Repo, "show server_version"),
+ {num, _} <- Float.parse(version) do
+ num
+ else
+ e ->
+ Logger.warn(
+ "Could not get the postgres version: #{inspect(e)}.\nSetting the default value of 9.6"
+ )
+
+ 9.6
+ end
+
+ :persistent_term.put({Pleroma.Repo, :postgres_version}, version)
end
def load_custom_modules do
@@ -107,7 +133,7 @@ defmodule Pleroma.Application do
raise "Invalid custom modules"
{:ok, modules, _warnings} ->
- if @env != :test do
+ if @mix_env != :test do
Enum.each(modules, fn mod ->
Logger.info("Custom module loaded: #{inspect(mod)}")
end)
@@ -118,26 +144,6 @@ defmodule Pleroma.Application do
end
end
- defp setup_instrumenters do
- require Prometheus.Registry
-
- if Application.get_env(:prometheus, Pleroma.Repo.Instrumenter) do
- :ok =
- :telemetry.attach(
- "prometheus-ecto",
- [:pleroma, :repo, :query],
- &Pleroma.Repo.Instrumenter.handle_event/4,
- %{}
- )
-
- Pleroma.Repo.Instrumenter.setup()
- end
-
- Pleroma.Web.Endpoint.MetricsExporter.setup()
- Pleroma.Web.Endpoint.PipelineInstrumenter.setup()
- Pleroma.Web.Endpoint.Instrumenter.setup()
- end
-
defp cachex_children do
[
build_cachex("used_captcha", ttl_interval: seconds_valid_interval()),
@@ -145,10 +151,16 @@ defmodule Pleroma.Application do
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),
+ build_cachex("scrubber_management", limit: 2500),
build_cachex("idempotency", expiration: idempotency_expiration(), limit: 2500),
build_cachex("web_resp", limit: 2500),
build_cachex("emoji_packs", expiration: emoji_packs_expiration(), limit: 10),
- build_cachex("failed_proxy_url", limit: 2500)
+ build_cachex("failed_proxy_url", limit: 2500),
+ build_cachex("banned_urls", default_ttl: :timer.hours(24 * 30), limit: 5_000),
+ build_cachex("translations", default_ttl: :timer.hours(24 * 30), limit: 2500),
+ build_cachex("instances", default_ttl: :timer.hours(24), ttl_interval: 1000, limit: 2500),
+ build_cachex("request_signatures", default_ttl: :timer.hours(24 * 30), limit: 3000),
+ build_cachex("rel_me", default_ttl: :timer.hours(24 * 30), limit: 300)
]
end
@@ -161,26 +173,34 @@ defmodule Pleroma.Application do
defp seconds_valid_interval,
do: :timer.seconds(Config.get!([Pleroma.Captcha, :seconds_valid]))
- defp build_cachex(type, opts),
+ @spec build_cachex(String.t(), keyword()) :: map()
+ def build_cachex(type, opts),
do: %{
id: String.to_atom("cachex_" <> type),
start: {Cachex, :start_link, [String.to_atom(type <> "_cache"), opts]},
type: :worker
}
- defp chat_enabled?, do: Config.get([:chat, :enabled])
-
- defp streamer_child(env) when env in [:test, :benchmark], do: []
+ defp dont_run_in_test(env) when env in [:test, :benchmark], do: []
- defp streamer_child(_) do
- [Pleroma.Web.Streamer.supervisor()]
+ defp dont_run_in_test(_) do
+ [
+ {Registry,
+ [
+ name: Pleroma.Web.Streamer.registry(),
+ keys: :duplicate,
+ partitions: System.schedulers_online()
+ ]}
+ ] ++ background_migrators()
end
- defp chat_child(_env, true) do
- [Pleroma.Web.ChatChannel.ChatChannelState]
+ defp background_migrators do
+ [
+ Pleroma.Migrators.HashtagsTableMigrator
+ ]
end
- defp chat_child(_, _), do: []
+ @spec task_children(atom()) :: [map()]
defp task_children(:test) do
[
@@ -207,30 +227,48 @@ defmodule Pleroma.Application do
]
end
- # start hackney and gun pools in tests
- defp http_children(_, :test) do
- hackney_options = Config.get([:hackney_pools, :federation])
- hackney_pool = :hackney_pool.child_spec(:federation, hackney_options)
- [hackney_pool, Pleroma.Pool.Supervisor]
+ @spec elasticsearch_children :: [Pleroma.Search.Elasticsearch.Cluster]
+ def elasticsearch_children do
+ config = Config.get([Pleroma.Search, :module])
+
+ if config == Pleroma.Search.Elasticsearch do
+ [Pleroma.Search.Elasticsearch.Cluster]
+ else
+ []
+ end
end
- defp http_children(Tesla.Adapter.Hackney, _) do
- pools = [:federation, :media]
+ @spec limiters_setup() :: :ok
+ def limiters_setup do
+ config = Config.get(ConcurrentLimiter, [])
- pools =
- if Config.get([Pleroma.Upload, :proxy_remote]) do
- [:upload | pools]
- else
- pools
- end
+ [
+ Pleroma.Web.RichMedia.Helpers,
+ Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy,
+ Pleroma.Search
+ ]
+ |> Enum.each(fn module ->
+ mod_config = Keyword.get(config, module, [])
- for pool <- pools do
- options = Config.get([:hackney_pools, pool])
- :hackney_pool.child_spec(pool, options)
- end
+ 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)
end
- defp http_children(Tesla.Adapter.Gun, _), do: [Pleroma.Pool.Supervisor]
+ defp http_children do
+ proxy_url = Config.get([:http, :proxy_url])
+ proxy = Pleroma.HTTP.AdapterHelper.format_proxy(proxy_url)
+ pool_size = Config.get([:http, :pool_size])
- defp http_children(_, _), do: []
+ config =
+ [:http, :adapter]
+ |> Config.get([])
+ |> Pleroma.HTTP.AdapterHelper.add_pool_size(pool_size)
+ |> Pleroma.HTTP.AdapterHelper.maybe_add_proxy_pool(proxy)
+ |> Keyword.put(:name, MyFinch)
+
+ [{Finch, config}]
+ end
end