changed CHANGELOG.md
 
@@ -1,5 1,15 @@
1
1
# Changelog
2
2
3
## v0.18.0 (2024-02-09)
4
5
### Enhancements
6
7
- Add Finch name to telemetry events #252
8
9
### Bug Fixes
10
11
- Fix several minor dialyzer errors and run dialyzer in CI #259, #261
12
3
13
## v0.17.0 (2024-01-07)
4
14
5
15
### Enhancements
changed README.md
 
@@ -107,7 107,7 @@ The package can be installed by adding `finch` to your list of dependencies in `
107
107
```elixir
108
108
def deps do
109
109
[
110
- {:finch, "~> 0.17"}
110
{:finch, "~> 0.18"}
111
111
]
112
112
end
113
113
```
changed hex_metadata.config
 
@@ -2,7 2,7 @@
2
2
[{<<"Changelog">>,<<"https://hexdocs.pm/finch/changelog.html">>},
3
3
{<<"GitHub">>,<<"https://github.com/sneako/finch">>}]}.
4
4
{<<"name">>,<<"finch">>}.
5
- {<<"version">>,<<"0.17.0">>}.
5
{<<"version">>,<<"0.18.0">>}.
6
6
{<<"description">>,<<"An HTTP client focused on performance.">>}.
7
7
{<<"elixir">>,<<"~> 1.11">>}.
8
8
{<<"app">>,<<"finch">>}.
 
@@ -44,8 44,8 @@
44
44
<<"lib/finch/http1/pool_metrics.ex">>,<<"lib/finch/http2">>,
45
45
<<"lib/finch/http2/request_stream.ex">>,<<"lib/finch/http2/pool.ex">>,
46
46
<<"lib/finch/http2/pool_metrics.ex">>,<<"lib/finch/request.ex">>,
47
- <<"lib/finch/ssl.ex">>,<<"lib/finch/telemetry.ex">>,
48
- <<"lib/finch/response.ex">>,<<"lib/finch/pool.ex">>,
49
- <<"lib/finch/pool_manager.ex">>,<<"lib/finch.ex">>,<<".formatter.exs">>,
47
<<"lib/finch/ssl.ex">>,<<"lib/finch/response.ex">>,
48
<<"lib/finch/pool_manager.ex">>,<<"lib/finch/pool.ex">>,
49
<<"lib/finch/telemetry.ex">>,<<"lib/finch.ex">>,<<".formatter.exs">>,
50
50
<<"mix.exs">>,<<"README.md">>,<<"LICENSE.md">>,<<"CHANGELOG.md">>]}.
51
51
{<<"build_tools">>,[<<"mix">>]}.
changed lib/finch.ex
 
@@ -90,7 90,7 @@ defmodule Finch do
90
90
],
91
91
start_pool_metrics?: [
92
92
type: :boolean,
93
- doc: "When true, pool metrics will be collected and avaiable through Finch.pool_status/2",
93
doc: "When true, pool metrics will be collected and available through Finch.pool_status/2",
94
94
default: false
95
95
]
96
96
]
 
@@ -104,7 104,7 @@ defmodule Finch do
104
104
105
105
@type scheme_host_port() :: {scheme(), host :: String.t(), port :: :inet.port_number()}
106
106
107
- @type request_opt() :: {:pool_timeout, pos_integer()} | {:receive_timeout, pos_integer()}
107
@type request_opt() :: {:pool_timeout, timeout()} | {:receive_timeout, timeout()}
108
108
109
109
@typedoc """
110
110
Options used by request functions.
 
@@ -360,10 360,9 @@ defmodule Finch do
360
360
{:ok, acc} | {:error, Exception.t()}
361
361
when acc: term()
362
362
def stream(%Request{} = req, name, acc, fun, opts \\ []) when is_function(fun, 2) do
363
- fun =
364
- fn entry, acc ->
365
- {:cont, fun.(entry, acc)}
366
- end
363
fun = fn entry, acc ->
364
{:cont, fun.(entry, acc)}
365
end
367
366
368
367
stream_while(req, name, acc, fun, opts)
369
368
end
 
@@ -427,7 426,7 @@ defmodule Finch do
427
426
428
427
defp __stream__(%Request{} = req, name, acc, fun, opts) do
429
428
{pool, pool_mod} = get_pool(req, name)
430
- pool_mod.request(pool, req, acc, fun, opts)
429
pool_mod.request(pool, req, acc, fun, name, opts)
431
430
end
432
431
433
432
@doc """
 
@@ -560,7 559,7 @@ defmodule Finch do
560
559
@spec async_request(Request.t(), name(), request_opts()) :: request_ref()
561
560
def async_request(%Request{} = req, name, opts \\ []) do
562
561
{pool, pool_mod} = get_pool(req, name)
563
- pool_mod.async_request(pool, req, opts)
562
pool_mod.async_request(pool, req, name, opts)
564
563
end
565
564
566
565
@doc """
changed lib/finch/http1/conn.ex
 
@@ -17,22 17,24 @@ defmodule Finch.HTTP1.Conn do
17
17
}
18
18
end
19
19
20
- def connect(%{mint: mint} = conn) when not is_nil(mint) do
20
def connect(%{mint: mint} = conn, name) when not is_nil(mint) do
21
21
meta = %{
22
22
scheme: conn.scheme,
23
23
host: conn.host,
24
- port: conn.port
24
port: conn.port,
25
name: name
25
26
}
26
27
27
28
Telemetry.event(:reused_connection, %{}, meta)
28
29
{:ok, conn}
29
30
end
30
31
31
- def connect(%{mint: nil} = conn) do
32
def connect(%{mint: nil} = conn, name) do
32
33
meta = %{
33
34
scheme: conn.scheme,
34
35
host: conn.host,
35
- port: conn.port
36
port: conn.port,
37
name: name
36
38
}
37
39
38
40
start_time = Telemetry.start(:connect, meta)
 
@@ -98,12 100,12 @@ defmodule Finch.HTTP1.Conn do
98
100
end
99
101
end
100
102
101
- def request(%{mint: nil} = conn, _, _, _, _, _, _), do: {:error, conn, "Could not connect"}
103
def request(%{mint: nil} = conn, _, _, _, _, _, _, _), do: {:error, conn, "Could not connect"}
102
104
103
- def request(conn, req, acc, fun, receive_timeout, request_timeout, idle_time) do
105
def request(conn, req, acc, fun, name, receive_timeout, request_timeout, idle_time) do
104
106
full_path = Finch.Request.request_path(req)
105
107
106
- metadata = %{request: req}
108
metadata = %{request: req, name: name}
107
109
108
110
extra_measurements = %{idle_time: idle_time}
changed lib/finch/http1/pool.ex
 
@@ -16,8 16,7 @@ defmodule Finch.HTTP1.Pool do
16
16
pool_max_idle_time,
17
17
_start_pool_metrics?,
18
18
_pool_idx
19
- } =
20
- opts
19
} = opts
21
20
22
21
%{
23
22
id: __MODULE__,
 
@@ -40,12 39,13 @@ defmodule Finch.HTTP1.Pool do
40
39
end
41
40
42
41
@impl Finch.Pool
43
- def request(pool, req, acc, fun, opts) do
42
def request(pool, req, acc, fun, name, opts) do
44
43
pool_timeout = Keyword.get(opts, :pool_timeout, 5_000)
45
44
receive_timeout = Keyword.get(opts, :receive_timeout, 15_000)
46
45
request_timeout = Keyword.get(opts, :request_timeout, :infinity)
47
46
48
- metadata = %{request: req, pool: pool}
47
metadata = %{request: req, pool: pool, name: name}
48
49
49
start_time = Telemetry.start(:queue, metadata)
50
50
51
51
try do
 
@@ -55,9 55,18 @@ defmodule Finch.HTTP1.Pool do
55
55
fn from, {state, conn, idle_time} ->
56
56
Telemetry.stop(:queue, start_time, metadata, %{idle_time: idle_time})
57
57
58
- with {:ok, conn} <- Conn.connect(conn),
58
with {:ok, conn} <- Conn.connect(conn, name),
59
59
{:ok, conn, acc} <-
60
- Conn.request(conn, req, acc, fun, receive_timeout, request_timeout, idle_time) do
60
Conn.request(
61
conn,
62
req,
63
acc,
64
fun,
65
name,
66
receive_timeout,
67
request_timeout,
68
idle_time
69
) do
61
70
{{:ok, acc}, transfer_if_open(conn, state, from)}
62
71
else
63
72
{:error, conn, error} ->
 
@@ -90,7 99,7 @@ defmodule Finch.HTTP1.Pool do
90
99
end
91
100
92
101
@impl Finch.Pool
93
- def async_request(pool, req, opts) do
102
def async_request(pool, req, name, opts) do
94
103
owner = self()
95
104
96
105
pid =
 
@@ -103,6 112,7 @@ defmodule Finch.HTTP1.Pool do
103
112
req,
104
113
{owner, monitor, request_ref},
105
114
&send_async_response/2,
115
name,
106
116
opts
107
117
) do
108
118
{:ok, _} -> send(owner, {request_ref, :done})
changed lib/finch/http1/pool_metrics.ex
 
@@ -45,7 45,7 @@ defmodule Finch.HTTP1.PoolMetrics do
45
45
46
46
def maybe_add(nil, _metrics_list), do: :ok
47
47
48
- def maybe_add(ref, metrics_list) when is_reference(ref) do
48
def maybe_add(ref, metrics_list) do
49
49
Enum.each(metrics_list, fn {metric_name, val} ->
50
50
:atomics.add(ref, @atomic_idx[metric_name], val)
51
51
end)
 
@@ -57,7 57,9 @@ defmodule Finch.HTTP1.PoolMetrics do
57
57
|> get_pool_status()
58
58
end
59
59
60
- def get_pool_status(ref) when is_reference(ref) do
60
def get_pool_status(nil), do: {:error, :not_found}
61
62
def get_pool_status(ref) do
61
63
%{
62
64
pool_idx: pool_idx,
63
65
pool_size: pool_size,
 
@@ -76,6 78,4 @@ defmodule Finch.HTTP1.PoolMetrics do
76
78
77
79
{:ok, result}
78
80
end
79
-
80
- def get_pool_status(nil), do: {:error, :not_found}
81
81
end
changed lib/finch/http2/pool.ex
 
@@ -30,7 30,7 @@ defmodule Finch.HTTP2.Pool do
30
30
# Call the pool with the request. The pool will multiplex multiple requests
31
31
# and stream the result set back to the calling process using `send`
32
32
@impl Finch.Pool
33
- def request(pool, request, acc, fun, opts) do
33
def request(pool, request, acc, fun, name, opts) do
34
34
opts = Keyword.put_new(opts, :receive_timeout, @default_receive_timeout)
35
35
timeout = opts[:receive_timeout]
36
36
request_ref = make_request_ref(pool)
 
@@ -48,7 48,8 @@ defmodule Finch.HTTP2.Pool do
48
48
response_waiting_loop(acc, fun, request_ref, monitor, fail_safe_timeout, :headers)
49
49
catch
50
50
kind, error ->
51
- Telemetry.exception(:recv, recv_start, kind, error, __STACKTRACE__, %{request: request})
51
metadata = %{request: request, name: name}
52
Telemetry.exception(:recv, recv_start, kind, error, __STACKTRACE__, metadata)
52
53
53
54
:ok = :gen_statem.call(pool, {:cancel, request_ref})
54
55
clean_responses(request_ref)
 
@@ -60,7 61,7 @@ defmodule Finch.HTTP2.Pool do
60
61
end
61
62
62
63
@impl Finch.Pool
63
- def async_request(pool, req, opts) do
64
def async_request(pool, req, _name, opts) do
64
65
opts = Keyword.put_new(opts, :receive_timeout, @default_receive_timeout)
65
66
request_ref = make_request_ref(pool)
66
67
 
@@ -264,7 265,8 @@ defmodule Finch.HTTP2.Pool do
264
265
metadata = %{
265
266
scheme: data.scheme,
266
267
host: data.host,
267
- port: data.port
268
port: data.port,
269
name: data.finch_name
268
270
}
269
271
270
272
start = Telemetry.start(:connect, metadata)
 
@@ -529,7 531,7 @@ defmodule Finch.HTTP2.Pool do
529
531
end
530
532
531
533
defp send_request(from, from_pid, request_ref, req, opts, data) do
532
- telemetry_metadata = %{request: req}
534
telemetry_metadata = %{request: req, name: data.finch_name}
533
535
534
536
request = %{
535
537
stream: RequestStream.new(req.body),
changed lib/finch/http2/pool_metrics.ex
 
@@ -35,7 35,7 @@ defmodule Finch.HTTP2.PoolMetrics do
35
35
36
36
def maybe_add(nil, _metrics_list), do: :ok
37
37
38
- def maybe_add(ref, metrics_list) when is_reference(ref) do
38
def maybe_add(ref, metrics_list) do
39
39
Enum.each(metrics_list, fn {metric_name, val} ->
40
40
:atomics.add(ref, @atomic_idx[metric_name], val)
41
41
end)
 
@@ -47,7 47,9 @@ defmodule Finch.HTTP2.PoolMetrics do
47
47
|> get_pool_status()
48
48
end
49
49
50
- def get_pool_status(ref) when is_reference(ref) do
50
def get_pool_status(nil), do: {:error, :not_found}
51
52
def get_pool_status(ref) do
51
53
%{
52
54
pool_idx: pool_idx,
53
55
in_flight_requests: in_flight_requests
 
@@ -63,6 65,4 @@ defmodule Finch.HTTP2.PoolMetrics do
63
65
64
66
{:ok, result}
65
67
end
66
-
67
- def get_pool_status(nil), do: {:error, :not_found}
68
68
end
changed lib/finch/pool.ex
 
@@ -9,12 9,17 @@ defmodule Finch.Pool do
9
9
Finch.Request.t(),
10
10
acc,
11
11
Finch.stream(acc),
12
Finch.name(),
12
13
list()
13
- ) ::
14
- {:ok, acc} | {:error, term()}
14
) :: {:ok, acc} | {:error, term()}
15
15
when acc: term()
16
16
17
- @callback async_request(pid(), Finch.Request.t(), list()) :: request_ref()
17
@callback async_request(
18
pid(),
19
Finch.Request.t(),
20
Finch.name(),
21
list()
22
) :: request_ref()
18
23
19
24
@callback cancel_async_request(request_ref()) :: :ok
changed lib/finch/telemetry.ex
 
@@ -63,6 63,7 @@ defmodule Finch.Telemetry do
63
63
64
64
#### Metadata
65
65
66
* `:name` - The name of the Finch instance.
66
67
* `:pool` - The pool's PID.
67
68
* `:request` - The request (`Finch.Request`).
68
69
 
@@ -77,6 78,7 @@ defmodule Finch.Telemetry do
77
78
78
79
#### Metadata
79
80
81
* `:name` - The name of the Finch instance.
80
82
* `:pool` - The pool's PID.
81
83
* `:request` - The request (`Finch.Request`).
82
84
 
@@ -90,6 92,7 @@ defmodule Finch.Telemetry do
90
92
91
93
#### Metadata
92
94
95
* `:name` - The name of the Finch instance.
93
96
* `:request` - The request (`Finch.Request`).
94
97
* `:kind` - The type of exception.
95
98
* `:reason` - Error description or error data.
 
@@ -106,6 109,7 @@ defmodule Finch.Telemetry do
106
109
107
110
#### Metadata
108
111
112
* `:name` - The name of the Finch instance.
109
113
* `:scheme` - The scheme used in the connection. either `http` or `https`.
110
114
* `:host` - The host address.
111
115
* `:port` - The port to connect on.
 
@@ -120,6 124,7 @@ defmodule Finch.Telemetry do
120
124
121
125
#### Metadata
122
126
127
* `:name` - The name of the Finch instance.
123
128
* `:scheme` - The scheme used in the connection. either `http` or `https`.
124
129
* `:host` - The host address.
125
130
* `:port` - The port to connect on.
 
@@ -131,6 136,7 @@ defmodule Finch.Telemetry do
131
136
132
137
#### Measurements
133
138
139
* `:name` - The name of the Finch instance.
134
140
* `:system_time` - The system time.
135
141
* `:idle_time` - Elapsed time since the connection was last checked in or initialized.
136
142
 
@@ -144,6 150,7 @@ defmodule Finch.Telemetry do
144
150
145
151
#### Measurements
146
152
153
* `:name` - The name of the Finch instance.
147
154
* `:duration` - Time taken to make the request.
148
155
* `:idle_time` - Elapsed time since the connection was last checked in or initialized.
149
156
 
@@ -163,6 170,7 @@ defmodule Finch.Telemetry do
163
170
164
171
#### Metadata
165
172
173
* `:name` - The name of the Finch instance.
166
174
* `:request` - The request (`Finch.Request`).
167
175
168
176
### Receive Stop
 
@@ -176,6 184,7 @@ defmodule Finch.Telemetry do
176
184
177
185
#### Metadata
178
186
187
* `:name` - The name of the Finch instance.
179
188
* `:request` - The request (`Finch.Request`).
180
189
* `:status` - The response status (`Mint.Types.status()`).
181
190
* `:headers` - The response headers (`Mint.Types.headers()`).
 
@@ -192,6 201,7 @@ defmodule Finch.Telemetry do
192
201
193
202
#### Metadata
194
203
204
* `:name` - The name of the Finch instance.
195
205
* `:request` - The request (`Finch.Request`).
196
206
* `:kind` - The type of exception.
197
207
* `:reason` - Error description or error data.
 
@@ -203,6 213,7 @@ defmodule Finch.Telemetry do
203
213
204
214
#### Metadata
205
215
216
* `:name` - The name of the Finch instance.
206
217
* `:scheme` - The scheme used in the connection. either `http` or `https`.
207
218
* `:host` - The host address.
208
219
* `:port` - The port to connect on.
changed mix.exs
 
@@ -2,7 2,7 @@ defmodule Finch.MixProject do
2
2
use Mix.Project
3
3
4
4
@name "Finch"
5
- @version "0.17.0"
5
@version "0.18.0"
6
6
@repo_url "https://github.com/sneako/finch"
7
7
8
8
def project do