Fork of Pleroma with site-specific changes and feature branches https://git.pleroma.social/pleroma/pleroma
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

263 line
7.5KB

  1. # Pleroma: A lightweight social networking server
  2. # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
  3. # SPDX-License-Identifier: AGPL-3.0-only
  4. defmodule Pleroma.Application do
  5. use Application
  6. import Cachex.Spec
  7. alias Pleroma.Config
  8. require Logger
  9. @name Mix.Project.config()[:name]
  10. @version Mix.Project.config()[:version]
  11. @repository Mix.Project.config()[:source_url]
  12. @env Mix.env()
  13. def name, do: @name
  14. def version, do: @version
  15. def named_version, do: @name <> " " <> @version
  16. def repository, do: @repository
  17. def user_agent do
  18. if Process.whereis(Pleroma.Web.Endpoint) do
  19. case Config.get([:http, :user_agent], :default) do
  20. :default ->
  21. info = "#{Pleroma.Web.base_url()} <#{Config.get([:instance, :email], "")}>"
  22. named_version() <> "; " <> info
  23. custom ->
  24. custom
  25. end
  26. else
  27. # fallback, if endpoint is not started yet
  28. "Pleroma Data Loader"
  29. end
  30. end
  31. # See http://elixir-lang.org/docs/stable/elixir/Application.html
  32. # for more information on OTP Applications
  33. def start(_type, _args) do
  34. # Scrubbers are compiled at runtime and therefore will cause a conflict
  35. # every time the application is restarted, so we disable module
  36. # conflicts at runtime
  37. Code.compiler_options(ignore_module_conflict: true)
  38. # Disable warnings_as_errors at runtime, it breaks Phoenix live reload
  39. # due to protocol consolidation warnings
  40. Code.compiler_options(warnings_as_errors: false)
  41. Pleroma.Telemetry.Logger.attach()
  42. Config.Holder.save_default()
  43. Pleroma.HTML.compile_scrubbers()
  44. Pleroma.Config.Oban.warn()
  45. Config.DeprecationWarnings.warn()
  46. Pleroma.Web.Plugs.HTTPSecurityPlug.warn_if_disabled()
  47. Pleroma.ApplicationRequirements.verify!()
  48. setup_instrumenters()
  49. load_custom_modules()
  50. Pleroma.Docs.JSON.compile()
  51. adapter = Application.get_env(:tesla, :adapter)
  52. if adapter == Tesla.Adapter.Gun do
  53. if version = Pleroma.OTPVersion.version() do
  54. [major, minor] =
  55. version
  56. |> String.split(".")
  57. |> Enum.map(&String.to_integer/1)
  58. |> Enum.take(2)
  59. if (major == 22 and minor < 2) or major < 22 do
  60. raise "
  61. !!!OTP VERSION WARNING!!!
  62. You are using gun adapter with OTP version #{version}, which doesn't support correct handling of unordered certificates chains. Please update your Erlang/OTP to at least 22.2.
  63. "
  64. end
  65. else
  66. raise "
  67. !!!OTP VERSION WARNING!!!
  68. To support correct handling of unordered certificates chains - OTP version must be > 22.2.
  69. "
  70. end
  71. end
  72. # Define workers and child supervisors to be supervised
  73. children =
  74. [
  75. Pleroma.Repo,
  76. Config.TransferTask,
  77. Pleroma.Emoji,
  78. Pleroma.Web.Plugs.RateLimiter.Supervisor
  79. ] ++
  80. cachex_children() ++
  81. http_children(adapter, @env) ++
  82. [
  83. Pleroma.Stats,
  84. Pleroma.JobQueueMonitor,
  85. {Oban, Config.get(Oban)}
  86. ] ++
  87. task_children(@env) ++
  88. dont_run_in_test(@env) ++
  89. chat_child(@env, chat_enabled?()) ++
  90. [
  91. Pleroma.Web.Endpoint,
  92. Pleroma.Gopher.Server
  93. ]
  94. # See http://elixir-lang.org/docs/stable/elixir/Supervisor.html
  95. # for other strategies and supported options
  96. opts = [strategy: :one_for_one, name: Pleroma.Supervisor]
  97. Supervisor.start_link(children, opts)
  98. end
  99. def load_custom_modules do
  100. dir = Config.get([:modules, :runtime_dir])
  101. if dir && File.exists?(dir) do
  102. dir
  103. |> Pleroma.Utils.compile_dir()
  104. |> case do
  105. {:error, _errors, _warnings} ->
  106. raise "Invalid custom modules"
  107. {:ok, modules, _warnings} ->
  108. if @env != :test do
  109. Enum.each(modules, fn mod ->
  110. Logger.info("Custom module loaded: #{inspect(mod)}")
  111. end)
  112. end
  113. :ok
  114. end
  115. end
  116. end
  117. defp setup_instrumenters do
  118. require Prometheus.Registry
  119. if Application.get_env(:prometheus, Pleroma.Repo.Instrumenter) do
  120. :ok =
  121. :telemetry.attach(
  122. "prometheus-ecto",
  123. [:pleroma, :repo, :query],
  124. &Pleroma.Repo.Instrumenter.handle_event/4,
  125. %{}
  126. )
  127. Pleroma.Repo.Instrumenter.setup()
  128. end
  129. Pleroma.Web.Endpoint.MetricsExporter.setup()
  130. Pleroma.Web.Endpoint.PipelineInstrumenter.setup()
  131. Pleroma.Web.Endpoint.Instrumenter.setup()
  132. end
  133. defp cachex_children do
  134. [
  135. build_cachex("used_captcha", ttl_interval: seconds_valid_interval()),
  136. build_cachex("user", default_ttl: 25_000, ttl_interval: 1000, limit: 2500),
  137. build_cachex("object", default_ttl: 25_000, ttl_interval: 1000, limit: 2500),
  138. build_cachex("rich_media", default_ttl: :timer.minutes(120), limit: 5000),
  139. build_cachex("scrubber", limit: 2500),
  140. build_cachex("idempotency", expiration: idempotency_expiration(), limit: 2500),
  141. build_cachex("web_resp", limit: 2500),
  142. build_cachex("emoji_packs", expiration: emoji_packs_expiration(), limit: 10),
  143. build_cachex("failed_proxy_url", limit: 2500),
  144. build_cachex("banned_urls", default_ttl: :timer.hours(24 * 30), limit: 5_000)
  145. ]
  146. end
  147. defp emoji_packs_expiration,
  148. do: expiration(default: :timer.seconds(5 * 60), interval: :timer.seconds(60))
  149. defp idempotency_expiration,
  150. do: expiration(default: :timer.seconds(6 * 60 * 60), interval: :timer.seconds(60))
  151. defp seconds_valid_interval,
  152. do: :timer.seconds(Config.get!([Pleroma.Captcha, :seconds_valid]))
  153. @spec build_cachex(String.t(), keyword()) :: map()
  154. def build_cachex(type, opts),
  155. do: %{
  156. id: String.to_atom("cachex_" <> type),
  157. start: {Cachex, :start_link, [String.to_atom(type <> "_cache"), opts]},
  158. type: :worker
  159. }
  160. defp chat_enabled?, do: Config.get([:chat, :enabled])
  161. defp dont_run_in_test(env) when env in [:test, :benchmark], do: []
  162. defp dont_run_in_test(_) do
  163. [
  164. {Registry,
  165. [
  166. name: Pleroma.Web.Streamer.registry(),
  167. keys: :duplicate,
  168. partitions: System.schedulers_online()
  169. ]},
  170. Pleroma.Web.FedSockets.Supervisor
  171. ]
  172. end
  173. defp chat_child(_env, true) do
  174. [Pleroma.Web.ChatChannel.ChatChannelState]
  175. end
  176. defp chat_child(_, _), do: []
  177. defp task_children(:test) do
  178. [
  179. %{
  180. id: :web_push_init,
  181. start: {Task, :start_link, [&Pleroma.Web.Push.init/0]},
  182. restart: :temporary
  183. }
  184. ]
  185. end
  186. defp task_children(_) do
  187. [
  188. %{
  189. id: :web_push_init,
  190. start: {Task, :start_link, [&Pleroma.Web.Push.init/0]},
  191. restart: :temporary
  192. },
  193. %{
  194. id: :internal_fetch_init,
  195. start: {Task, :start_link, [&Pleroma.Web.ActivityPub.InternalFetchActor.init/0]},
  196. restart: :temporary
  197. }
  198. ]
  199. end
  200. # start hackney and gun pools in tests
  201. defp http_children(_, :test) do
  202. http_children(Tesla.Adapter.Hackney, nil) ++ http_children(Tesla.Adapter.Gun, nil)
  203. end
  204. defp http_children(Tesla.Adapter.Hackney, _) do
  205. pools = [:federation, :media]
  206. pools =
  207. if Config.get([Pleroma.Upload, :proxy_remote]) do
  208. [:upload | pools]
  209. else
  210. pools
  211. end
  212. for pool <- pools do
  213. options = Config.get([:hackney_pools, pool])
  214. :hackney_pool.child_spec(pool, options)
  215. end
  216. end
  217. defp http_children(Tesla.Adapter.Gun, _) do
  218. Pleroma.Gun.ConnectionPool.children() ++
  219. [{Task, &Pleroma.HTTP.AdapterHelper.Gun.limiter_setup/0}]
  220. end
  221. defp http_children(_, _), do: []
  222. end