@@ -176,33 +176,33 @@ defmodule Finch.HTTP1.Pool do
176
176
# to determine the correct pool module to use to make the request
177
177
{ :ok , _ } = Registry . register ( registry , shp , __MODULE__ )
178
178
179
- { :ok , { registry , shp , pool_idx , metric_ref , opts , System . monotonic_time ( :millisecond ) } }
179
+ { :ok , { registry , shp , pool_idx , metric_ref , opts , init_activity_info ( ) } }
180
180
end
181
181
182
182
@ impl NimblePool
183
183
def init_worker (
184
- { _name , { scheme , host , port } , _pool_idx , _metric_ref , opts , _last_checkout_at } =
184
+ { _name , { scheme , host , port } , _pool_idx , _metric_ref , opts , _actt_info } =
185
185
pool_state
186
186
) do
187
187
{ :ok , Conn . new ( scheme , host , port , opts , self ( ) ) , pool_state }
188
188
end
189
189
190
190
@ impl NimblePool
191
191
def handle_checkout ( :checkout , _ , % { mint: nil } = conn , pool_state ) do
192
- { _name , _shp , _pool_idx , metric_ref , _opts , _last_checkout_ts } = pool_state
192
+ { _name , _shp , _pool_idx , metric_ref , _opts , _actt_info } = pool_state
193
193
idle_time = System . monotonic_time ( ) - conn . last_checkin
194
194
PoolMetrics . maybe_add ( metric_ref , in_use_connections: 1 )
195
195
{ :ok , { :fresh , conn , idle_time } , conn , pool_state }
196
196
end
197
197
198
198
def handle_checkout ( :checkout , _from , conn , pool_state ) do
199
199
idle_time = System . monotonic_time ( ) - conn . last_checkin
200
- { _name , { scheme , host , port } , _pool_idx , metric_ref , _opts , _last_checkout_ts } = pool_state
200
+ { _name , { scheme , host , port } , _pool_idx , metric_ref , _opts , _actt_info } = pool_state
201
201
202
202
with true <- Conn . reusable? ( conn , idle_time ) ,
203
203
{ :ok , conn } <- Conn . set_mode ( conn , :passive ) do
204
204
PoolMetrics . maybe_add ( metric_ref , in_use_connections: 1 )
205
- { :ok , { :reuse , conn , idle_time } , conn , update_last_checkout_ts ( pool_state ) }
205
+ { :ok , { :reuse , conn , idle_time } , conn , update_activity_info ( :checkout , pool_state ) }
206
206
else
207
207
false ->
208
208
meta = % {
@@ -225,15 +225,19 @@ defmodule Finch.HTTP1.Pool do
225
225
226
226
@ impl NimblePool
227
227
def handle_checkin ( checkin , _from , _old_conn , pool_state ) do
228
- { _name , _shp , _pool_idx , metric_ref , _opts , _last_checkout_ts } = pool_state
228
+ { _name , _shp , _pool_idx , metric_ref , _opts , _actt_info } = pool_state
229
229
PoolMetrics . maybe_add ( metric_ref , in_use_connections: - 1 )
230
230
231
231
with { :ok , conn } <- checkin ,
232
232
{ :ok , conn } <- Conn . set_mode ( conn , :active ) do
233
- { :ok , % { conn | last_checkin: System . monotonic_time ( ) } , pool_state }
233
+ {
234
+ :ok ,
235
+ % { conn | last_checkin: System . monotonic_time ( ) } ,
236
+ update_activity_info ( :checkin , pool_state )
237
+ }
234
238
else
235
239
_ ->
236
- { :remove , :closed , pool_state }
240
+ { :remove , :closed , update_activity_info ( :checkin , pool_state ) }
237
241
end
238
242
end
239
243
@@ -253,14 +257,24 @@ defmodule Finch.HTTP1.Pool do
253
257
254
258
@ impl NimblePool
255
259
def handle_ping ( conn , pool_state ) do
256
- { _name , { scheme , host , port } , _pool_idx , _metric_ref , opts , last_checkout_ts } = pool_state
260
+ { _name , { scheme , host , port } , _pool_idx , _metric_ref , opts , activity_info } = pool_state
257
261
258
262
max_idle_time = Map . get ( opts , :pool_max_idle_time , :infinity )
259
263
now = System . monotonic_time ( :millisecond )
260
- diff_from_last_checkout = now - last_checkout_ts
264
+ diff_from_last_checkout = now - activity_info . last_checkout_ts
265
+
266
+ is_idle? = diff_from_last_checkout > max_idle_time
267
+ max_idle_time_configured? = is_number ( max_idle_time )
268
+ any_connection_in_use? = activity_info . in_use_count > 0
261
269
262
270
cond do
263
- is_number ( max_idle_time ) and diff_from_last_checkout > max_idle_time ->
271
+ not max_idle_time_configured? ->
272
+ { :ok , conn }
273
+
274
+ any_connection_in_use? ->
275
+ { :ok , conn }
276
+
277
+ is_idle? ->
264
278
meta = % {
265
279
scheme: scheme ,
266
280
host: host ,
@@ -285,7 +299,7 @@ defmodule Finch.HTTP1.Pool do
285
299
286
300
@ impl NimblePool
287
301
def handle_cancelled ( :checked_out , pool_state ) do
288
- { _name , _shp , _pool_idx , metric_ref , _opts , _last_checkout_ts } = pool_state
302
+ { _name , _shp , _pool_idx , metric_ref , _opts , _actt_info } = pool_state
289
303
PoolMetrics . maybe_add ( metric_ref , in_use_connections: - 1 )
290
304
:ok
291
305
end
@@ -315,6 +329,22 @@ defmodule Finch.HTTP1.Pool do
315
329
defp pool_idle_timeout ( :infinity ) , do: nil
316
330
defp pool_idle_timeout ( pool_max_idle_time ) , do: pool_max_idle_time
317
331
318
- defp update_last_checkout_ts ( pool_state ) ,
319
- do: put_elem ( pool_state , 5 , System . monotonic_time ( :millisecond ) )
332
+ defp init_activity_info ( ) ,
333
+ do: % { in_use_count: 0 , last_checkout_ts: System . monotonic_time ( :millisecond ) }
334
+
335
+ defp update_activity_info ( :checkout , pool_state ) do
336
+ info = % { in_use_count: count } = elem ( pool_state , 5 )
337
+
338
+ put_elem ( pool_state , 5 , % {
339
+ info
340
+ | in_use_count: count + 1 ,
341
+ last_checkout_ts: System . monotonic_time ( :millisecond )
342
+ } )
343
+ end
344
+
345
+ defp update_activity_info ( :checkin , pool_state ) do
346
+ info = % { in_use_count: count } = elem ( pool_state , 5 )
347
+
348
+ put_elem ( pool_state , 5 , % { info | in_use_count: max ( count - 1 , 0 ) } )
349
+ end
320
350
end
0 commit comments