From 1583363981dd861a1356aa92ad361dc922ffa4eb Mon Sep 17 00:00:00 2001 From: David Bernheisel Date: Thu, 5 Oct 2023 04:51:29 -0400 Subject: [PATCH] Add :finch_private option to put into Finch.Request (#252) --- lib/req.ex | 4 ++++ lib/req/steps.ex | 13 +++++++++++++ test/req/steps_test.exs | 24 ++++++++++++++++++++++++ 3 files changed, 41 insertions(+) diff --git a/lib/req.ex b/lib/req.ex index 0e6fe11d..e4f8d18f 100644 --- a/lib/req.ex +++ b/lib/req.ex @@ -293,6 +293,9 @@ defmodule Req do * `:unix_socket` - if set, connect through the given UNIX domain socket. + * `:finch_private` - a map or keyword list of private metadata to add to the Finch request. May be useful + for adding custom data when handling telemetry with `Finch.Telemetry`. + * `:finch_request` - a function that executes the Finch request, defaults to using `Finch.request/3`. ## Examples @@ -350,6 +353,7 @@ defmodule Req do :plug, :finch, :finch_request, + :finch_private, :connect_options, :inet6, :receive_timeout, diff --git a/lib/req/steps.ex b/lib/req/steps.ex index 5d39bc42..a2646318 100644 --- a/lib/req/steps.ex +++ b/lib/req/steps.ex @@ -587,6 +587,9 @@ defmodule Req.Steps do * `:unix_socket` - if set, connect through the given UNIX domain socket. + * `:finch_private` - a map or keyword list of private metadata to add to the Finch request. May be useful + for adding custom data when handling telemetry with `Finch.Telemetry`. + * `:finch_request` - a function that executes the Finch request, defaults to using `Finch.request/3`. The function should accept 4 arguments: @@ -675,6 +678,7 @@ defmodule Req.Steps do finch_request = Finch.build(request.method, request.url, request_headers, body) |> Map.replace!(:unix_socket, request.options[:unix_socket]) + |> add_private_options(request.options[:finch_private]) finch_options = request.options |> Map.take([:receive_timeout, :pool_timeout]) |> Enum.to_list() @@ -838,6 +842,15 @@ defmodule Req.Steps do end end + defp add_private_options(finch_request, nil), do: finch_request + + defp add_private_options(finch_request, private_options) + when is_list(private_options) or is_map(private_options) do + Enum.reduce(private_options, finch_request, fn {k, v}, acc_finch_req -> + Finch.Request.put_private(acc_finch_req, k, v) + end) + end + defp finch_fields_to_map(fields) do Enum.reduce(fields, %{}, fn {name, value}, acc -> Map.update(acc, name, [value], &(&1 ++ [value])) diff --git a/test/req/steps_test.exs b/test/req/steps_test.exs index bd7f071a..3086a75f 100644 --- a/test/req/steps_test.exs +++ b/test/req/steps_test.exs @@ -1648,6 +1648,30 @@ defmodule Req.StepsTest do end end + def send_telemetry_metadata_pid(_name, _measurements, metadata, _) do + send(metadata.request.private.pid, :telemetry_private) + :ok + end + + test ":finch_private", c do + on_exit(fn -> :telemetry.detach("#{c.test}") end) + + :ok = + :telemetry.attach( + "#{c.test}", + [:finch, :request, :stop], + &__MODULE__.send_telemetry_metadata_pid/4, + nil + ) + + Bypass.expect(c.bypass, "GET", "/ok", fn conn -> + Plug.Conn.send_resp(conn, 200, "finch_private") + end) + + assert Req.get!(c.url <> "/ok", finch_private: %{pid: self()}).body == "finch_private" + assert_received :telemetry_private + end + test "into: fun" do %{url: url} = TestSocket.serve(fn socket ->