Merge branch 'stable' into develop
[akkoma] / lib / pleroma / http / adapter_helper / gun.ex
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.HTTP.AdapterHelper.Gun do
6 @behaviour Pleroma.HTTP.AdapterHelper
7
8 alias Pleroma.Config
9 alias Pleroma.HTTP.AdapterHelper
10
11 require Logger
12
13 @defaults [
14 retry: 1,
15 retry_timeout: 1_000
16 ]
17
18 @type pool() :: :federation | :upload | :media | :default
19
20 @spec options(keyword(), URI.t()) :: keyword()
21 def options(incoming_opts \\ [], %URI{} = uri) do
22 proxy =
23 [:http, :proxy_url]
24 |> Config.get()
25 |> AdapterHelper.format_proxy()
26
27 config_opts = Config.get([:http, :adapter], [])
28
29 @defaults
30 |> Keyword.merge(config_opts)
31 |> add_scheme_opts(uri)
32 |> AdapterHelper.maybe_add_proxy(proxy)
33 |> Keyword.merge(incoming_opts)
34 |> put_timeout()
35 end
36
37 defp add_scheme_opts(opts, %{scheme: "http"}), do: opts
38
39 defp add_scheme_opts(opts, %{scheme: "https"}) do
40 Keyword.put(opts, :certificates_verification, true)
41 end
42
43 defp put_timeout(opts) do
44 {recv_timeout, opts} = Keyword.pop(opts, :recv_timeout, pool_timeout(opts[:pool]))
45 # this is the timeout to receive a message from Gun
46 # `:timeout` key is used in Tesla
47 Keyword.put(opts, :timeout, recv_timeout)
48 end
49
50 @spec pool_timeout(pool()) :: non_neg_integer()
51 def pool_timeout(pool) do
52 default = Config.get([:pools, :default, :recv_timeout], 5_000)
53
54 Config.get([:pools, pool, :recv_timeout], default)
55 end
56
57 def limiter_setup do
58 prefix = Pleroma.Gun.ConnectionPool
59 wait = Config.get([:connections_pool, :connection_acquisition_wait])
60 retries = Config.get([:connections_pool, :connection_acquisition_retries])
61
62 :pools
63 |> Config.get([])
64 |> Enum.each(fn {name, opts} ->
65 max_running = Keyword.get(opts, :size, 50)
66 max_waiting = Keyword.get(opts, :max_waiting, 10)
67
68 result =
69 ConcurrentLimiter.new(:"#{prefix}.#{name}", max_running, max_waiting,
70 wait: wait,
71 max_retries: retries
72 )
73
74 case result do
75 :ok -> :ok
76 {:error, :existing} -> :ok
77 end
78 end)
79
80 :ok
81 end
82 end