summaryrefslogtreecommitdiff
path: root/lib/pleroma/tesla/middleware/connection_pool.ex
blob: de74270f87f282c8d510130304ffe20eca4c2919 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# Pleroma: A lightweight social networking server
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only

defmodule Pleroma.Tesla.Middleware.ConnectionPool do
  @moduledoc """
  Middleware to get/release connections from `Pleroma.Gun.ConnectionPool`
  """

  @behaviour Tesla.Middleware

  alias Pleroma.Gun.ConnectionPool

  @impl Tesla.Middleware
  def call(%Tesla.Env{url: url, opts: opts} = env, next, _) do
    uri = URI.parse(url)

    # Avoid leaking connections when the middleware is called twice
    # with body_as: :chunks. We assume only the middleware can set
    # opts[:adapter][:conn]
    if opts[:adapter][:conn] do
      ConnectionPool.release_conn(opts[:adapter][:conn])
    end

    case ConnectionPool.get_conn(uri, opts[:adapter]) do
      {:ok, conn_pid} ->
        adapter_opts = Keyword.merge(opts[:adapter], conn: conn_pid, close_conn: false)
        opts = Keyword.put(opts, :adapter, adapter_opts)
        env = %{env | opts: opts}

        case Tesla.run(env, next) do
          {:ok, env} ->
            unless opts[:adapter][:body_as] == :chunks do
              ConnectionPool.release_conn(conn_pid)
              {_, res} = pop_in(env.opts[:adapter][:conn])
              {:ok, res}
            else
              {:ok, env}
            end

          err ->
            ConnectionPool.release_conn(conn_pid)
            err
        end

      err ->
        err
    end
  end
end