@@ -186,14 +186,15 @@ defmodule Mongo.Session do
186
186
187
187
@ doc """
188
188
Merge the session / transaction data into the cmd. There is no need to call this function directly. It is called automatically.
189
+ The global session timeout is merged to the options as well.
189
190
"""
190
- @ spec bind_session ( Session . t ( ) , BSON . document ( ) ) :: { :ok , pid , BSON . document ( ) } | { :error , term ( ) }
191
- def bind_session ( nil , _cmd ) do
191
+ @ spec bind_session ( Session . t ( ) , BSON . document ( ) , Keyword . t ( ) ) :: { :ok , pid , BSON . document ( ) , Keyword . t ( ) } | { :error , term ( ) }
192
+ def bind_session ( nil , _cmd , _opts ) do
192
193
{ :error , Mongo.Error . exception ( "No session" ) }
193
194
end
194
195
195
- def bind_session ( pid , cmd ) do
196
- call ( pid , { :bind_session , cmd } )
196
+ def bind_session ( pid , cmd , opts ) do
197
+ call ( pid , { :bind_session , cmd , opts } )
197
198
end
198
199
199
200
@ doc """
@@ -462,13 +463,16 @@ defmodule Mongo.Session do
462
463
##
463
464
# bind session: only if wire_version >= 6, MongoDB 3.6.x and no transaction is running: only lsid and the transaction-id is added
464
465
#
465
- def handle_call_event ( { :bind_session , cmd } , transaction , % Session { conn: conn , opts: opts , wire_version: wire_version , server_session: % ServerSession { session_id: id , txn_num: txn_num } } = data )
466
+ def handle_call_event ( { :bind_session , cmd , client_opts } , transaction , % Session { conn: conn , opts: opts , wire_version: wire_version , server_session: % ServerSession { session_id: id , txn_num: txn_num } } = data )
466
467
when wire_version >= 6 and transaction in [ :no_transaction , :transaction_aborted , :transaction_committed ] do
467
468
## only if retryable_writes are enabled!
468
469
options =
469
470
case opts [ :retryable_writes ] do
470
- true -> [ lsid: % { id: id } , txnNumber: % BSON.LongNumber { value: txn_num } , readConcern: read_concern ( data , Keyword . get ( cmd , :readConcern ) ) ]
471
- _ -> [ lsid: % { id: id } , readConcern: read_concern ( data , Keyword . get ( cmd , :readConcern ) ) ]
471
+ true ->
472
+ [ lsid: % { id: id } , txnNumber: % BSON.LongNumber { value: txn_num } , readConcern: read_concern ( data , Keyword . get ( cmd , :readConcern ) ) ]
473
+
474
+ _ ->
475
+ [ lsid: % { id: id } , readConcern: read_concern ( data , Keyword . get ( cmd , :readConcern ) ) ]
472
476
end
473
477
474
478
cmd =
@@ -477,11 +481,12 @@ defmodule Mongo.Session do
477
481
|> ReadPreference . add_read_preference ( opts )
478
482
|> filter_nils ( )
479
483
480
- { :keep_state_and_data , { :ok , conn , cmd } }
484
+ client_opts = merge_timeout ( client_opts , opts )
485
+ { :keep_state_and_data , { :ok , conn , cmd , client_opts } }
481
486
end
482
487
483
- def handle_call_event ( { :bind_session , cmd } , :starting_transaction , % Session { conn: conn , server_session: % ServerSession { session_id: id , txn_num: txn_num } , wire_version: wire_version } = data ) when wire_version >= 6 do
484
- result =
488
+ def handle_call_event ( { :bind_session , cmd , client_opts } , :starting_transaction , % Session { conn: conn , opts: opts , server_session: % ServerSession { session_id: id , txn_num: txn_num } , wire_version: wire_version } = data ) when wire_version >= 6 do
489
+ cmd =
485
490
Keyword . merge ( cmd ,
486
491
readConcern: read_concern ( data , Keyword . get ( cmd , :readConcern ) ) ,
487
492
lsid: % { id: id } ,
@@ -492,10 +497,11 @@ defmodule Mongo.Session do
492
497
|> filter_nils ( )
493
498
|> Keyword . drop ( ~w( writeConcern) a )
494
499
495
- { :next_state , :transaction_in_progress , { :ok , conn , result } }
500
+ client_opts = merge_timeout ( client_opts , opts )
501
+ { :next_state , :transaction_in_progress , { :ok , conn , cmd , client_opts } }
496
502
end
497
503
498
- def handle_call_event ( { :bind_session , cmd } , :transaction_in_progress , % Session { conn: conn , wire_version: wire_version , server_session: % ServerSession { session_id: id , txn_num: txn_num } } ) when wire_version >= 6 do
504
+ def handle_call_event ( { :bind_session , cmd , client_opts } , :transaction_in_progress , % Session { conn: conn , opts: opts , wire_version: wire_version , server_session: % ServerSession { session_id: id , txn_num: txn_num } } ) when wire_version >= 6 do
499
505
result =
500
506
Keyword . merge ( cmd ,
501
507
lsid: % { id: id } ,
@@ -504,12 +510,13 @@ defmodule Mongo.Session do
504
510
)
505
511
|> Keyword . drop ( ~w( writeConcern readConcern) a )
506
512
507
- { :keep_state_and_data , { :ok , conn , result } }
513
+ client_opts = merge_timeout ( client_opts , opts )
514
+ { :keep_state_and_data , { :ok , conn , result , client_opts } }
508
515
end
509
516
510
517
# In case of wire_version < 6 we do nothing
511
- def handle_call_event ( { :bind_session , cmd } , _transaction , % Session { conn: conn } ) do
512
- { :keep_state_and_data , { :ok , conn , cmd } }
518
+ def handle_call_event ( { :bind_session , cmd , client_opts } , _transaction , % Session { conn: conn } ) do
519
+ { :keep_state_and_data , { :ok , conn , cmd , client_opts } }
513
520
end
514
521
515
522
def handle_call_event ( { :commit_transaction , _start_time } , :starting_transaction , _data ) do
@@ -710,4 +717,14 @@ defmodule Mongo.Session do
710
717
def in_session ( session , _topology_pid , _read_write_type , fun , opts ) do
711
718
fun . ( session , opts )
712
719
end
720
+
721
+ defp merge_timeout ( opts , default_ops ) do
722
+ case Keyword . get ( default_ops , :timeout ) do
723
+ nil ->
724
+ opts
725
+
726
+ timeout ->
727
+ Keyword . put_new ( opts , :timeout , timeout )
728
+ end
729
+ end
713
730
end
0 commit comments