@@ -17,6 +17,7 @@ defmodule DBConnection.Connection do
17
17
use Connection
18
18
require Logger
19
19
alias DBConnection.Backoff
20
+ alias DBConnection.ConnectionPool
20
21
21
22
@ pool_timeout 5_000
22
23
@ timeout 15_000
@@ -83,6 +84,11 @@ defmodule DBConnection.Connection do
83
84
end
84
85
end
85
86
87
+ @ doc false
88
+ def ping ( { pid , ref } , state ) do
89
+ Connection . cast ( pid , { :ping , ref , state } )
90
+ end
91
+
86
92
## Internal API
87
93
88
94
@ doc false
@@ -96,19 +102,26 @@ defmodule DBConnection.Connection do
96
102
Supervisor.Spec . worker ( __MODULE__ , [ mod , opts , mode ] , child_opts )
97
103
end
98
104
105
+ @ doc false
106
+ def child_spec ( mod , opts , mode , info , child_opts ) do
107
+ Supervisor.Spec . worker ( __MODULE__ , [ mod , opts , mode , info ] , child_opts )
108
+ end
109
+
99
110
## Connection API
100
111
101
112
@ doc false
102
113
def init ( { mod , opts , mode , info } ) do
103
- queue = if mode == :sojourn , do: :broker , else: :queue . new ( )
114
+ queue = if mode in [ :connection , :poolboy ] , do: :queue . new ( ) , else: mode
115
+ idle = if mode in [ :connection , :poolboy ] , do: get_idle ( opts ) , else: :passive
104
116
broker = if mode == :sojourn , do: elem ( info , 0 )
105
117
regulator = if mode == :sojourn , do: elem ( info , 1 )
106
- idle = if mode == :sojourn , do: :passive , else: get_idle ( opts )
107
118
after_timeout = if mode == :poolboy , do: :stop , else: :backoff
119
+ pool = if mode == :connection_pool , do: elem ( info , 0 )
120
+ tag = if mode == :connection_pool , do: elem ( info , 1 )
108
121
109
122
s = % { mod: mod , opts: opts , state: nil , client: :closed , broker: broker ,
110
- regulator: regulator , lock: nil , queue: queue , timer: nil ,
111
- backoff: Backoff . new ( opts ) ,
123
+ regulator: regulator , lock: nil , pool: pool , tag: tag , queue: queue ,
124
+ timer: nil , backoff: Backoff . new ( opts ) ,
112
125
after_connect: Keyword . get ( opts , :after_connect ) ,
113
126
after_connect_timeout: Keyword . get ( opts , :after_connect_timeout ,
114
127
@ timeout ) , idle: idle ,
@@ -206,7 +219,7 @@ defmodule DBConnection.Connection do
206
219
@ doc false
207
220
def handle_call ( { :checkout , ref , queue? , timeout } , { pid , _ } = from , s ) do
208
221
case s do
209
- % { queue: :broker } ->
222
+ % { queue: mode } when is_atom ( mode ) ->
210
223
exit ( :bad_checkout )
211
224
% { client: nil , idle: :passive , mod: mod , state: state } ->
212
225
Connection . reply ( from , { :ok , { self ( ) , ref } , mod , state } )
@@ -244,6 +257,16 @@ defmodule DBConnection.Connection do
244
257
end
245
258
246
259
@ doc false
260
+ def handle_cast ( { :ping , ref , state } , % { client: { ref , :pool } } = s ) do
261
+ % { mod: mod } = s
262
+ case apply ( mod , :ping , [ state ] ) do
263
+ { :ok , state } ->
264
+ pool_update ( state , s )
265
+ { :disconnect , err , state } ->
266
+ { :disconnect , { :log , err } , % { s | state: state } }
267
+ end
268
+ end
269
+
247
270
def handle_cast ( { :checkin , ref , state } , % { client: { ref , _ } } = s ) do
248
271
handle_next ( state , s )
249
272
end
@@ -259,7 +282,7 @@ defmodule DBConnection.Connection do
259
282
{ :stop , { err , stack } , % { s | state: state } }
260
283
end
261
284
262
- def handle_cast ( { :cancel , _ } , % { queue: :broker } ) do
285
+ def handle_cast ( { :cancel , _ } , % { queue: mode } ) when is_atom ( mode ) do
263
286
exit ( :bad_cancel )
264
287
end
265
288
def handle_cast ( { :cancel , ref } , % { client: { ref , _ } , state: state } = s ) do
@@ -308,7 +331,9 @@ defmodule DBConnection.Connection do
308
331
def handle_cast ( { :connected , ref } , % { client: { ref , :connect } } = s ) do
309
332
% { mod: mod , state: state , queue: queue , broker: broker } = s
310
333
case apply ( mod , :checkout , [ state ] ) do
311
- { :ok , state } when queue == :broker ->
334
+ { :ok , state } when queue == :connection_pool ->
335
+ pool_update ( state , s )
336
+ { :ok , state } when queue == :sojourn ->
312
337
info = { self ( ) , mod , state }
313
338
{ :await , ^ ref , _ } = :sbroker . async_ask_r ( broker , info , { self ( ) , ref } )
314
339
{ :noreply , % { s | client: { ref , :broker } , state: state } }
@@ -335,7 +360,8 @@ defmodule DBConnection.Connection do
335
360
err = DBConnection.ConnectionError . exception ( message )
336
361
{ :disconnect , { down_log ( reason ) , err } , % { s | client: { ref , nil } } }
337
362
end
338
- def handle_info ( { :DOWN , _ , :process , _ , _ } = msg , % { queue: :broker } = s ) do
363
+ def handle_info ( { :DOWN , _ , :process , _ , _ } = msg , % { queue: mode } = s )
364
+ when is_atom ( mode ) do
339
365
do_handle_info ( msg , s )
340
366
end
341
367
def handle_info ( { :DOWN , ref , :process , _ , _ } = msg , % { queue: queue } = s ) do
@@ -425,7 +451,7 @@ defmodule DBConnection.Connection do
425
451
defp start_opts ( :connection , opts ) do
426
452
Keyword . take ( opts , [ :debug , :name , :timeout , :spawn_opt ] )
427
453
end
428
- defp start_opts ( mode , opts ) when mode in [ :poolboy , :sojourn ] do
454
+ defp start_opts ( mode , opts ) when mode in [ :poolboy , :sojourn , :connection_pool ] do
429
455
Keyword . take ( opts , [ :debug , :spawn_opt ] )
430
456
end
431
457
@@ -486,7 +512,10 @@ defmodule DBConnection.Connection do
486
512
demonitor ( client )
487
513
handle_next ( state , % { s | client: nil , backoff: backoff } )
488
514
end
489
- defp handle_next ( state , % { queue: :broker } = s ) do
515
+ defp handle_next ( state , % { queue: :connection_pool } = s ) do
516
+ pool_update ( state , s )
517
+ end
518
+ defp handle_next ( state , % { queue: :sojourn } = s ) do
490
519
% { client: client , timer: timer , mod: mod , broker: broker } = s
491
520
demonitor ( client )
492
521
cancel_timer ( timer )
@@ -626,7 +655,9 @@ defmodule DBConnection.Connection do
626
655
end
627
656
end
628
657
629
- defp clear_queue ( :broker ) , do: :broker
658
+ defp clear_queue ( queue ) when is_atom ( queue ) do
659
+ queue
660
+ end
630
661
defp clear_queue ( queue ) do
631
662
clear =
632
663
fn ( { { _ , mon } , _ , from } ) ->
@@ -645,6 +676,11 @@ defmodule DBConnection.Connection do
645
676
:ok
646
677
end
647
678
679
+ defp pool_update ( state , % { pool: pool , tag: tag , mod: mod } = s ) do
680
+ ref = ConnectionPool . update ( pool , tag , mod , state )
681
+ { :noreply , % { s | client: { ref , :pool } , state: state } , :hibernate }
682
+ end
683
+
648
684
defp normal_status ( mod , pdict , state ) do
649
685
try do
650
686
mod . format_status ( :normal , [ pdict , state ] )
0 commit comments