Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions lib/req.ex
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,17 @@ defmodule Req do
Finch options ([`run_finch`](`Req.Steps.run_finch/1`) step), see `Finch.start_link/1` for options:

* `:finch` - the Finch pool to use. Defaults to pool automatically started by `Req`.
Can be either a pool name (atom) or a `{name, opts}` tuple where `opts` can include:

* `:pool_tag` - (requires Finch v0.22+) the tag to use when selecting which Finch pool to
use for a request. Defaults to `:default`. This allows routing requests to different
pools for the same host. See `Finch.Pool.new/2` for more information on configuring
tagged pools.

Examples:

Req.get!("https://api.example.com/data", finch: MyFinch)
Req.get!("https://api.example.com/data", finch: {MyFinch, pool_tag: :bulk})

* `:connect_options` - dynamically starts (or re-uses already started) Finch pool with
the given connection options (see `Mint.HTTP.connect/4` for options):
Expand Down
42 changes: 25 additions & 17 deletions lib/req/finch.ex
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ defmodule Req.Finch do
request
end

finch_name = finch_name(request)
{finch_name, options} = finch_name_options(request)

# TODO: Remove when :finch_request is removed
if match?(
Expand Down Expand Up @@ -76,9 +76,15 @@ defmodule Req.Finch do
{:stream, enumerable}
end

options =
if unix_socket = request.options[:unix_socket] do
Keyword.put(options, :unix_socket, unix_socket)
else
options
end

finch_request =
Finch.build(request.method, request.url, request_headers, body)
|> Map.replace!(:unix_socket, request.options[:unix_socket])
Finch.build(request.method, request.url, request_headers, body, options)
|> add_private_options(request.options[:finch_private])

finch_options =
Expand Down Expand Up @@ -411,19 +417,12 @@ defmodule Req.Finch do
end
end

defp finch_name(request) do
defp finch_name_options(request) do
custom_options? =
Map.has_key?(request.options, :connect_options) or Map.has_key?(request.options, :inet6)

cond do
name = request.options[:finch] ->
if Map.has_key?(request.options, :connect_options) do
raise ArgumentError, "cannot set both :finch and :connect_options"
else
name
end

custom_options? ->
case request.options[:finch] do
nil when custom_options? ->
pool_options = pool_options(request.options)

name =
Expand All @@ -439,14 +438,23 @@ defmodule Req.Finch do
{Finch, name: name, pools: %{default: pool_options}}
) do
{:ok, _} ->
name
{name, []}

{:error, {:already_started, _}} ->
name
{name, []}
end

true ->
Req.Finch
nil ->
{Req.Finch, []}

_ when is_map_key(request.options, :connect_options) ->
raise ArgumentError, "cannot set both :finch and :connect_options"

name when is_atom(name) ->
{name, []}

{name, options} when is_atom(name) ->
{name, Keyword.validate!(options, [:pool_tag])}
end
end

Expand Down
11 changes: 11 additions & 0 deletions lib/req/steps.ex
Original file line number Diff line number Diff line change
Expand Up @@ -815,6 +815,17 @@ defmodule Req.Steps do
## Request Options

* `:finch` - the name of the Finch pool. Defaults to a pool automatically started by Req.
Can be either a pool name (atom) or a `{name, opts}` tuple where `opts` can include:

* `:pool_tag` - (requires Finch v0.22+) the tag to use when selecting which Finch pool to
use for a request. Defaults to `:default`. This allows routing requests to different
pools for the same host. See `Finch.Pool.new/2` for more information on configuring
tagged pools.

Examples:

Req.get!("https://api.example.com/data", finch: MyFinch)
Req.get!("https://api.example.com/data", finch: {MyFinch, pool_tag: :bulk})

* `:connect_options` - dynamically starts (or re-uses already started) Finch pool with
the given connection options:
Expand Down
24 changes: 24 additions & 0 deletions test/req/finch_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -650,5 +650,29 @@ defmodule Req.FinchTest do
conn_opts: [transport_opts: [timeout: 0, inet6: true, cacerts: []]]
]
end

def send_pool_tag(_name, _measurements, metadata, _config) do
if pid = metadata.request.private[:pid] do
send(pid, {:pool_tag, metadata.request.pool_tag})
end

:ok
end

test ":finch {name, pool_tag: tag} sets the request's pool_tag", %{test: test} do
on_exit(fn -> :telemetry.detach("#{test}") end)

:telemetry.attach("#{test}", [:finch, :request, :stop], &__MODULE__.send_pool_tag/4, nil)

%{url: url} =
start_http_server(fn conn ->
Plug.Conn.send_resp(conn, 200, "ok")
end)

assert Req.get!(url, finch: {Req.Finch, pool_tag: :bulk}, finch_private: %{pid: self()}).body ==
"ok"

assert_received {:pool_tag, :bulk}
end
end
end
Loading