Skip to main content

lib/salemove/http_client/application.ex

defmodule Salemove.HttpClient.Application do
  @moduledoc """
  Starts the default Finch pool used by `Tesla.Adapter.Finch`, the default
  adapter.

  The pool is only started when the library is actually configured to use the
  Finch adapter: `:finch` must be available (it is an optional dependency -
  add it to your application's dependencies) and the adapter configured via
  the `:salemove_http_client` application environment must resolve to
  `Tesla.Adapter.Finch` (the default when no adapter is configured). Clients
  selecting the Finch adapter per module or per request must start their own
  named Finch instance.

  The pool is registered under the name `Salemove.HttpClient.Finch` and can be
  configured via the `:finch_pools` application environment, which is passed
  verbatim as the `:pools` option to `Finch.start_link/1`:

      config :salemove_http_client,
        finch_pools: %{
          default: [size: 50, conn_max_idle_time: 30_000, conn_opts: [transport_opts: [timeout: 1_500]]]
        }

  Applications that need several pools (or per-host TLS/proxy settings) can
  either configure them here or start their own named `Finch` instance and
  point clients at it with `adapter_options: [name: MyApp.Finch]`.
  """

  use Application

  require Logger

  @impl true
  def start(_type, _args) do
    Supervisor.start_link(children(), strategy: :one_for_one, name: Salemove.HttpClient.Supervisor)
  end

  @doc false
  @spec children() :: [Supervisor.child_spec() | {module, term}]
  def children do
    cond do
      configured_adapter() != Salemove.HttpClient.default_adapter() ->
        []

      not Code.ensure_loaded?(Finch) ->
        Logger.warning(
          "Salemove.HttpClient is configured to use Tesla.Adapter.Finch, but :finch is " <>
            "not available - the default Finch pool is not started and requests will fail. " <>
            "Add {:finch, \"~> 0.23\"} to your application's dependencies, or configure " <>
            "a different adapter."
        )

        []

      true ->
        [
          {Finch,
           name: Salemove.HttpClient.Finch,
           pools: Application.get_env(:salemove_http_client, :finch_pools, default_pools())}
        ]
    end
  end

  defp configured_adapter do
    Application.get_env(:salemove_http_client, :adapter, Salemove.HttpClient.default_adapter())
  end

  defp default_pools do
    %{default: [conn_max_idle_time: 30_000, conn_opts: [transport_opts: [timeout: 1_500]]]}
  end
end