lib/core/shared_db_connection_pool.ex

defmodule Legendary.Core.SharedDBConnectionPool do
  @moduledoc """
  A shareable connection pool. We use this so that all the apps connecting to
  one database can use on connection pool, even if they have different repos.

  This allows a reasonable number of connections to be available per application
  without requiring a huge number of connections to the database.
  """
  alias DBConnection.ConnectionPool

  def start_link({mod, opts}) do
    case GenServer.start_link(
           ConnectionPool,
           {mod, opts},
           Keyword.take(opts, [:name, :spawn_opt])
         ) do
      {:ok, pid} -> {:ok, pid}
      {:error, {:already_started, pid}} -> {:ok, pid}
      error -> error
    end
  end

  defdelegate checkout(pool, caller, opts), to: ConnectionPool

  def child_spec({mod, opts}) do
    opts = Keyword.put_new(opts, :name, key(opts))

    %{
      id: __MODULE__,
      start: {Legendary.Core.SharedDBConnectionPool, :start_link, [{mod, opts}]}
    }
  end

  # sobelow_skip ["DOS.StringToAtom"]
  defp key(opts) do
    key_hash =
      case opts do
        %{url: url} ->
          Ecto.Repo.Supervisor.parse_url(url)

        _ ->
          opts
      end
      |> hash_opts()

    String.to_atom("Legendary.Core.SharedDBConnectionPool.#{key_hash}")
  end

  defp hash_opts(opts) do
    unhashed_key =
      opts
      |> Keyword.take([:hostname, :username, :password, :database])
      |> Keyword.values()
      |> Enum.join("/")

    :crypto.hash(:sha3_256, unhashed_key) |> Base.encode16()
  end
end