@@ -56,7 +56,8 @@ defmodule DBConnection.Ownership.Manager do
56
56
:ok | { :already , :owner | :allowed } | :not_found
57
57
def allow ( manager , parent , allow , opts ) do
58
58
timeout = Keyword . get ( opts , :timeout , @ timeout )
59
- GenServer . call ( manager , { :allow , parent , allow } , timeout )
59
+ passed_opts = Keyword . take ( opts , [ :unallow_existing ] )
60
+ GenServer . call ( manager , { :allow , parent , allow , passed_opts } , timeout )
60
61
end
61
62
62
63
@ spec get_connection_metrics ( GenServer . server ( ) ) ::
@@ -170,15 +171,24 @@ defmodule DBConnection.Ownership.Manager do
170
171
{ :reply , reply , state }
171
172
end
172
173
173
- def handle_call ( { :allow , caller , allow } , _from , % { checkouts: checkouts } = state ) do
174
- if kind = already_checked_out ( checkouts , allow ) do
174
+ def handle_call ( { :allow , caller , allow , opts } , _from , % { checkouts: checkouts } = state ) do
175
+ unallow_existing = Keyword . get ( opts , :unallow_existing , false )
176
+ kind = already_checked_out ( checkouts , allow )
177
+
178
+ if ! unallow_existing && kind do
175
179
{ :reply , { :already , kind } , state }
176
180
else
177
181
case Map . get ( checkouts , caller , :not_found ) do
178
182
{ :owner , ref , proxy } ->
183
+ state =
184
+ if unallow_existing , do: owner_unallow ( state , caller , allow , ref , proxy ) , else: state
185
+
179
186
{ :reply , :ok , owner_allow ( state , caller , allow , ref , proxy ) }
180
187
181
188
{ :allowed , ref , proxy } ->
189
+ state =
190
+ if unallow_existing , do: owner_unallow ( state , caller , allow , ref , proxy ) , else: state
191
+
182
192
{ :reply , :ok , owner_allow ( state , caller , allow , ref , proxy ) }
183
193
184
194
:not_found ->
@@ -310,6 +320,24 @@ defmodule DBConnection.Ownership.Manager do
310
320
state
311
321
end
312
322
323
+ defp owner_unallow ( % { ets: ets , log: log } = state , caller , unallow , ref , proxy ) do
324
+ if log do
325
+ Logger . log ( log , fn ->
326
+ [ inspect ( unallow ) , " was unallowed by " , inspect ( caller ) , " on proxy " , inspect ( proxy ) ]
327
+ end )
328
+ end
329
+
330
+ state = update_in ( state . checkouts , & Map . delete ( & 1 , unallow ) )
331
+
332
+ state =
333
+ update_in ( state . owners [ ref ] , fn { proxy , caller , allowed } ->
334
+ { proxy , caller , List . delete ( allowed , unallow ) }
335
+ end )
336
+
337
+ ets && :ets . delete ( ets , { unallow , proxy } )
338
+ state
339
+ end
340
+
313
341
defp owner_down ( % { ets: ets , log: log } = state , ref ) do
314
342
case get_and_update_in ( state . owners , & Map . pop ( & 1 , ref ) ) do
315
343
{ { proxy , caller , allowed } , state } ->
0 commit comments