First
[anni] / lib / pleroma / tesla / middleware / connection_pool.ex
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Tesla.Middleware.ConnectionPool do
6   @moduledoc """
7   Middleware to get/release connections from `Pleroma.Gun.ConnectionPool`
8   """
9
10   @behaviour Tesla.Middleware
11
12   alias Pleroma.Gun.ConnectionPool
13
14   @impl Tesla.Middleware
15   def call(%Tesla.Env{url: url, opts: opts} = env, next, _) do
16     uri = URI.parse(url)
17
18     # Avoid leaking connections when the middleware is called twice
19     # with body_as: :chunks. We assume only the middleware can set
20     # opts[:adapter][:conn]
21     if opts[:adapter][:conn] do
22       ConnectionPool.release_conn(opts[:adapter][:conn])
23     end
24
25     case ConnectionPool.get_conn(uri, opts[:adapter]) do
26       {:ok, conn_pid} ->
27         adapter_opts = Keyword.merge(opts[:adapter], conn: conn_pid, close_conn: false)
28         opts = Keyword.put(opts, :adapter, adapter_opts)
29         env = %{env | opts: opts}
30
31         case Tesla.run(env, next) do
32           {:ok, env} ->
33             unless opts[:adapter][:body_as] == :chunks do
34               ConnectionPool.release_conn(conn_pid)
35               {_, res} = pop_in(env.opts[:adapter][:conn])
36               {:ok, res}
37             else
38               {:ok, env}
39             end
40
41           err ->
42             ConnectionPool.release_conn(conn_pid)
43             err
44         end
45
46       err ->
47         err
48     end
49   end
50 end