added gun connections holder genserver
This commit is contained in:
parent
2469061657
commit
aa0ab31b5b
@ -35,7 +35,8 @@ defmodule Pleroma.Application do
|
||||
Pleroma.Emoji,
|
||||
Pleroma.Captcha,
|
||||
Pleroma.FlakeId,
|
||||
Pleroma.ScheduledActivityWorker
|
||||
Pleroma.ScheduledActivityWorker,
|
||||
Pleroma.Gun.Connections
|
||||
] ++
|
||||
cachex_children() ++
|
||||
hackney_pool_children() ++
|
||||
|
@ -26,8 +26,8 @@ defmodule Pleroma.Gun.Connections do
|
||||
{:ok, %__MODULE__{conns: %{}}}
|
||||
end
|
||||
|
||||
@spec get_conn(atom(), String.t(), keyword()) :: pid()
|
||||
def get_conn(name \\ __MODULE__, url, opts \\ []) do
|
||||
@spec get_conn(String.t(), keyword(), atom()) :: pid()
|
||||
def get_conn(url, opts \\ [], name \\ __MODULE__) do
|
||||
opts = Enum.into(opts, %{})
|
||||
uri = URI.parse(url)
|
||||
|
||||
@ -39,6 +39,27 @@ defmodule Pleroma.Gun.Connections do
|
||||
)
|
||||
end
|
||||
|
||||
# TODO: only for testing, add this parameter to the config
|
||||
@spec try_to_get_gun_conn(String.t(), keyword(), atom()) :: nil | pid()
|
||||
def try_to_get_gun_conn(url, opts \\ [], name \\ __MODULE__),
|
||||
do: try_to_get_gun_conn(url, opts, name, 0)
|
||||
|
||||
@spec try_to_get_gun_conn(String.t(), keyword(), atom(), pos_integer()) :: nil | pid()
|
||||
def try_to_get_gun_conn(_url, _, _, 3), do: nil
|
||||
|
||||
def try_to_get_gun_conn(url, opts, name, acc) do
|
||||
case Pleroma.Gun.Connections.get_conn(url, opts, name) do
|
||||
nil -> try_to_get_gun_conn(url, acc + 1)
|
||||
conn -> conn
|
||||
end
|
||||
end
|
||||
|
||||
@spec alive?(atom()) :: boolean()
|
||||
def alive?(name \\ __MODULE__) do
|
||||
pid = Process.whereis(name)
|
||||
if pid, do: Process.alive?(pid), else: false
|
||||
end
|
||||
|
||||
@spec get_state(atom()) :: t()
|
||||
def get_state(name \\ __MODULE__) do
|
||||
GenServer.call(name, {:state})
|
||||
|
@ -32,6 +32,15 @@ defmodule Pleroma.HTTP do
|
||||
process_request_options(options)
|
||||
|> process_sni_options(url)
|
||||
|
||||
adapter_gun? = Application.get_env(:tesla, :adapter) == Tesla.Adapter.Gun
|
||||
|
||||
options =
|
||||
if adapter_gun? and Pleroma.Gun.Connections.alive?() do
|
||||
get_conn_for_gun(url, options)
|
||||
else
|
||||
options
|
||||
end
|
||||
|
||||
params = Keyword.get(options, :params, [])
|
||||
|
||||
%{}
|
||||
@ -52,6 +61,20 @@ defmodule Pleroma.HTTP do
|
||||
end
|
||||
end
|
||||
|
||||
defp get_conn_for_gun(url, options) do
|
||||
case Pleroma.Gun.Connections.try_to_get_gun_conn(url) do
|
||||
nil ->
|
||||
options
|
||||
|
||||
conn ->
|
||||
adapter_opts =
|
||||
Keyword.get(options, :adapter, [])
|
||||
|> Keyword.put(:conn, conn)
|
||||
|
||||
Keyword.put(options, :adapter, adapter_opts)
|
||||
end
|
||||
end
|
||||
|
||||
defp process_sni_options(options, nil), do: options
|
||||
|
||||
defp process_sni_options(options, url) do
|
||||
|
@ -3,23 +3,56 @@
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Gun.ConnectionsTest do
|
||||
use ExUnit.Case, async: true
|
||||
use ExUnit.Case
|
||||
alias Pleroma.Gun.{Connections, Conn, API}
|
||||
|
||||
setup do
|
||||
name = :test_gun_connections
|
||||
adapter = Application.get_env(:tesla, :adapter)
|
||||
Application.put_env(:tesla, :adapter, Tesla.Adapter.Gun)
|
||||
on_exit(fn -> Application.put_env(:tesla, :adapter, adapter) end)
|
||||
{:ok, pid} = Connections.start_link(name)
|
||||
|
||||
{:ok, name: name, pid: pid}
|
||||
end
|
||||
|
||||
describe "alive?/2" do
|
||||
test "is alive", %{name: name} do
|
||||
assert Connections.alive?(name)
|
||||
end
|
||||
|
||||
test "returns false if not started" do
|
||||
refute Connections.alive?(:some_random_name)
|
||||
end
|
||||
end
|
||||
|
||||
test "try_to_get_gun_conn/1 returns conn", %{name: name, pid: pid} do
|
||||
conn = Connections.try_to_get_gun_conn("http://some-domain.com", [genserver_pid: pid], name)
|
||||
assert is_pid(conn)
|
||||
assert Process.alive?(conn)
|
||||
|
||||
reused_conn = Connections.get_conn("http://some-domain.com", [genserver_pid: pid], name)
|
||||
|
||||
assert conn == reused_conn
|
||||
|
||||
%Connections{
|
||||
conns: %{
|
||||
"some-domain.com:80" => %Conn{
|
||||
conn: ^conn,
|
||||
state: :up,
|
||||
waiting_pids: []
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
end
|
||||
|
||||
test "opens connection and reuse it on next request", %{name: name, pid: pid} do
|
||||
conn = Connections.get_conn(name, "http://some-domain.com", genserver_pid: pid)
|
||||
conn = Connections.get_conn("http://some-domain.com", [genserver_pid: pid], name)
|
||||
|
||||
assert is_pid(conn)
|
||||
assert Process.alive?(conn)
|
||||
|
||||
reused_conn = Connections.get_conn(name, "http://some-domain.com", genserver_pid: pid)
|
||||
reused_conn = Connections.get_conn("http://some-domain.com", [genserver_pid: pid], name)
|
||||
|
||||
assert conn == reused_conn
|
||||
|
||||
@ -35,15 +68,15 @@ defmodule Gun.ConnectionsTest do
|
||||
end
|
||||
|
||||
test "reuses connection based on protocol", %{name: name, pid: pid} do
|
||||
conn = Connections.get_conn(name, "http://some-domain.com", genserver_pid: pid)
|
||||
conn = Connections.get_conn("http://some-domain.com", [genserver_pid: pid], name)
|
||||
assert is_pid(conn)
|
||||
assert Process.alive?(conn)
|
||||
|
||||
https_conn = Connections.get_conn(name, "https://some-domain.com", genserver_pid: pid)
|
||||
https_conn = Connections.get_conn("https://some-domain.com", [genserver_pid: pid], name)
|
||||
|
||||
refute conn == https_conn
|
||||
|
||||
reused_https = Connections.get_conn(name, "https://some-domain.com", genserver_pid: pid)
|
||||
reused_https = Connections.get_conn("https://some-domain.com", [genserver_pid: pid], name)
|
||||
|
||||
refute conn == reused_https
|
||||
|
||||
@ -66,7 +99,7 @@ defmodule Gun.ConnectionsTest do
|
||||
end
|
||||
|
||||
test "process gun_down message", %{name: name, pid: pid} do
|
||||
conn = Connections.get_conn(name, "http://gun_down.com", genserver_pid: pid)
|
||||
conn = Connections.get_conn("http://gun_down.com", [genserver_pid: pid], name)
|
||||
|
||||
refute conn
|
||||
|
||||
@ -82,7 +115,7 @@ defmodule Gun.ConnectionsTest do
|
||||
end
|
||||
|
||||
test "process gun_down message and then gun_up", %{name: name, pid: pid} do
|
||||
conn = Connections.get_conn(name, "http://gun_down_and_up.com", genserver_pid: pid)
|
||||
conn = Connections.get_conn("http://gun_down_and_up.com", [genserver_pid: pid], name)
|
||||
|
||||
refute conn
|
||||
|
||||
@ -96,7 +129,7 @@ defmodule Gun.ConnectionsTest do
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
|
||||
conn = Connections.get_conn(name, "http://gun_down_and_up.com", genserver_pid: pid)
|
||||
conn = Connections.get_conn("http://gun_down_and_up.com", [genserver_pid: pid], name)
|
||||
|
||||
assert is_pid(conn)
|
||||
assert Process.alive?(conn)
|
||||
@ -116,7 +149,7 @@ defmodule Gun.ConnectionsTest do
|
||||
tasks =
|
||||
for _ <- 1..5 do
|
||||
Task.async(fn ->
|
||||
Connections.get_conn(name, "http://some-domain.com", genserver_pid: pid)
|
||||
Connections.get_conn("http://some-domain.com", [genserver_pid: pid], name)
|
||||
end)
|
||||
end
|
||||
|
||||
@ -149,12 +182,12 @@ defmodule Gun.ConnectionsTest do
|
||||
api = Pleroma.Config.get([API])
|
||||
Pleroma.Config.put([API], :gun)
|
||||
on_exit(fn -> Pleroma.Config.put([API], api) end)
|
||||
conn = Connections.get_conn(name, "http://httpbin.org")
|
||||
conn = Connections.get_conn("http://httpbin.org", [], name)
|
||||
|
||||
assert is_pid(conn)
|
||||
assert Process.alive?(conn)
|
||||
|
||||
reused_conn = Connections.get_conn(name, "http://httpbin.org")
|
||||
reused_conn = Connections.get_conn("http://httpbin.org", [], name)
|
||||
|
||||
assert conn == reused_conn
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.ReverseProxyTest do
|
||||
use Pleroma.Web.ConnCase, async: true
|
||||
use Pleroma.Web.ConnCase
|
||||
import ExUnit.CaptureLog
|
||||
import Mox
|
||||
alias Pleroma.ReverseProxy
|
||||
@ -322,6 +322,10 @@ defmodule Pleroma.ReverseProxyTest do
|
||||
adapter = Application.get_env(:tesla, :adapter)
|
||||
Application.put_env(:tesla, :adapter, Tesla.Adapter.Gun)
|
||||
|
||||
api = Pleroma.Config.get([Pleroma.Gun.API])
|
||||
Pleroma.Config.put([Pleroma.Gun.API], :gun)
|
||||
{:ok, _} = Pleroma.Gun.Connections.start_link(Pleroma.Gun.Connections)
|
||||
|
||||
conn = ReverseProxy.call(conn, "http://httpbin.org/stream-bytes/10")
|
||||
|
||||
assert byte_size(conn.resp_body) == 10
|
||||
@ -331,6 +335,7 @@ defmodule Pleroma.ReverseProxyTest do
|
||||
on_exit(fn ->
|
||||
Pleroma.Config.put([Pleroma.ReverseProxy.Client], client)
|
||||
Application.put_env(:tesla, :adapter, adapter)
|
||||
Pleroma.Config.put([Pleroma.Gun.API], api)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user