clean up and test coverage

This commit is contained in:
Alexander Strizhakov 2020-04-30 15:07:21 +03:00
parent 8e4bd2c1cf
commit a16fb7c35c
No known key found for this signature in database
GPG key ID: 022896A53AEF1381
8 changed files with 87 additions and 31 deletions

View file

@ -79,12 +79,6 @@ defmodule Mix.Tasks.Pleroma.Benchmark do
def run(["adapters"]) do
start_pleroma()
:ok =
Pleroma.Gun.Conn.open(
"https://httpbin.org/stream-bytes/1500",
:gun_connections
)
Process.sleep(1_500)
Benchee.run(

View file

@ -34,11 +34,8 @@ defmodule Pleroma.Gun.Conn do
crf: 1,
retries: 0
@spec open(String.t() | URI.t(), atom(), keyword()) :: :ok | nil
def open(url, name, opts \\ [])
def open(url, name, opts) when is_binary(url), do: open(URI.parse(url), name, opts)
def open(%URI{} = uri, name, opts) do
@spec open(URI.t(), atom(), keyword()) :: :ok
def open(%URI{} = uri, name, opts \\ []) do
pool_opts = Pleroma.Config.get([:connections_pool], [])
opts =
@ -62,7 +59,7 @@ defmodule Pleroma.Gun.Conn do
end
defp try_open(name, uri, opts, max_connections) do
if Connections.count(name) < max_connections do
if Connections.count(name) <= max_connections do
do_open(uri, opts)
else
close_least_used_and_do_open(name, uri, opts)

View file

@ -1,4 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2015-2020 Tymon Tobolski <https://github.com/teamon/tesla/blob/master/lib/tesla/middleware/follow_redirects.ex>
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only

View file

@ -16,21 +16,20 @@ defmodule Pleroma.Pool.Connections do
@type seconds :: pos_integer()
@type t :: %__MODULE__{
conns: %{domain() => conn()},
opts: keyword()
conns: %{domain() => conn()}
}
defstruct conns: %{}, opts: []
defstruct conns: %{}
@spec start_link({atom(), keyword()}) :: {:ok, pid()}
def start_link({name, opts}) do
GenServer.start_link(__MODULE__, opts, name: name)
@spec start_link(atom()) :: {:ok, pid()}
def start_link(name) do
GenServer.start_link(__MODULE__, [], name: name)
end
@impl true
def init(opts) do
def init(_) do
schedule_close_idle_conns()
{:ok, %__MODULE__{conns: %{}, opts: opts}}
{:ok, %__MODULE__{conns: %{}}}
end
@spec checkin(String.t() | URI.t(), atom()) :: pid() | nil
@ -43,11 +42,8 @@ defmodule Pleroma.Pool.Connections do
@spec alive?(atom()) :: boolean()
def alive?(name) do
if pid = Process.whereis(name) do
Process.alive?(pid)
else
false
end
pid = Process.whereis(name)
is_pid(pid) and Process.alive?(pid)
end
@spec get_state(atom()) :: t()

View file

@ -15,8 +15,7 @@ defmodule Pleroma.Pool.Supervisor do
def init(_) do
conns_child = %{
id: Pool.Connections,
start:
{Pool.Connections, :start_link, [{:gun_connections, Config.get([:connections_pool])}]}
start: {Pool.Connections, :start_link, [:gun_connections]}
}
Supervisor.init([conns_child | pools()], strategy: :one_for_one)

View file

@ -33,8 +33,6 @@ defmodule Pleroma.ReverseProxy.Client.Tesla do
else
{:ok, response.status, response.headers}
end
else
{:error, error} -> {:error, error}
end
end

View file

@ -9,6 +9,14 @@ defmodule Pleroma.HTTP.GunTest do
alias Pleroma.HTTP.Gun
describe "options/1" do
test "http" do
uri = URI.parse("http://example.com")
opts = Gun.options([reuse_conn: false], uri)
assert opts[:reuse_conn] == false
end
test "https url with default port" do
uri = URI.parse("https://example.com")

View file

@ -26,7 +26,7 @@ defmodule Pleroma.Pool.ConnectionsTest do
setup do
name = :test_connections
{:ok, pid} = Connections.start_link({name, []})
{:ok, pid} = Connections.start_link(name)
on_exit(fn ->
if Process.alive?(pid), do: GenServer.stop(name)
@ -97,6 +97,66 @@ defmodule Pleroma.Pool.ConnectionsTest do
end
end
describe "pool overflow" do
setup do: clear_config([:connections_pool, :max_connections], 2)
test "when all conns are active return nil", %{name: name} do
open_mock(2)
conn1 = Connections.checkin("https://example1.com", name)
conn2 = Connections.checkin("https://example2.com", name)
refute Connections.checkin("https://example3.com", name)
self = self()
assert match?(
%Connections{
conns: %{
"https:example1.com:443" => %Conn{
conn: ^conn1,
used_by: [{^self, _}]
},
"https:example2.com:443" => %Conn{
conn: ^conn2,
used_by: [{^self, _}]
}
}
},
Connections.get_state(name)
)
assert Connections.count(name) == 2
end
test "close idle conn", %{name: name} do
open_mock(3)
|> expect(:close, fn _ -> :ok end)
self = self()
conn1 = Connections.checkin("https://example1.com", name)
Connections.checkout(conn1, self, name)
conn2 = Connections.checkin("https://example2.com", name)
conn3 = Connections.checkin("https://example3.com", name)
assert match?(
%Connections{
conns: %{
"https:example2.com:443" => %Conn{
conn: ^conn2,
used_by: [{^self, _}]
},
"https:example3.com:443" => %Conn{
conn: ^conn3,
used_by: [{^self, _}]
}
}
},
Connections.get_state(name)
)
assert Connections.count(name) == 2
end
end
test "opens connection and reuse it on next request", %{name: name} do
open_mock()
url = "http://some-domain.com"
@ -376,6 +436,9 @@ defmodule Pleroma.Pool.ConnectionsTest do
refute Connections.checkin(url, name)
end) =~
"Opening connection to http://gun-not-up.com failed with error {:error, :timeout}"
state = Connections.get_state(name)
assert state.conns == %{}
end
test "process gun_down message and then gun_up", %{name: name} do
@ -784,7 +847,7 @@ defmodule Pleroma.Pool.ConnectionsTest do
test "count/1" do
name = :test_count
{:ok, _} = Connections.start_link({name, []})
{:ok, _} = Connections.start_link(name)
assert Connections.count(name) == 0
Connections.add_conn(name, "1", %Conn{conn: self()})
assert Connections.count(name) == 1