@@ -26,7 +26,7 @@ defmodule Mongo.Session do
26
26
# * `server_session` the server_session data
27
27
# * `opts` options
28
28
# * `implicit` true or false
29
- defstruct [ conn: nil , server_session: nil , implicit: false , opts: [ ] ]
29
+ defstruct [ conn: nil , server_session: nil , implicit: false , wire_version: 0 , opts: [ ] ]
30
30
31
31
@ impl true
32
32
def callback_mode ( ) do
@@ -36,9 +36,9 @@ defmodule Mongo.Session do
36
36
@ doc """
37
37
Start the generic state machine.
38
38
"""
39
- @ spec start_link ( GenServer . server , ServerSession . t , atom , keyword ( ) ) :: { :ok , Session . t } | :ignore | { :error , term ( ) }
40
- def start_link ( conn , server_session , type , opts ) do
41
- :gen_statem . start_link ( __MODULE__ , { conn , server_session , type , opts } , [ ] )
39
+ @ spec start_link ( GenServer . server , ServerSession . t , atom , integer , keyword ( ) ) :: { :ok , Session . t } | :ignore | { :error , term ( ) }
40
+ def start_link ( conn , server_session , type , wire_version , opts ) do
41
+ :gen_statem . start_link ( __MODULE__ , { conn , server_session , type , wire_version , opts } , [ ] )
42
42
end
43
43
44
44
@ doc """
@@ -126,21 +126,29 @@ defmodule Mongo.Session do
126
126
def alive? ( pid ) , do: Process . alive? ( pid )
127
127
128
128
@ impl true
129
- def init ( { conn , server_session , type , opts } ) do
129
+ def init ( { conn , server_session , type , wire_version , opts } ) do
130
130
data = % Session { conn: conn ,
131
131
server_session: server_session ,
132
- implicit: ( type == :implicit ) , opts: opts }
132
+ implicit: ( type == :implicit ) ,
133
+ wire_version: wire_version ,
134
+ opts: opts }
133
135
{ :ok , :no_transaction , data }
134
136
end
135
137
136
138
@ impl true
137
139
def handle_event ( { :call , from } , { :start_transaction } , state , % Session { server_session: session } = data ) when state in [ :no_transaction , :transaction_aborted , :transaction_committed ] do
138
140
{ :next_state , :starting_transaction , % Session { data | server_session: ServerSession . next_txn_num ( session ) } , { :reply , from , :ok } }
139
141
end
140
- def handle_event ( { :call , from } , { :bind_session , cmd } , :no_transaction , % Session { conn: conn , server_session: % ServerSession { session_id: id } } ) do
142
+ ##
143
+ # bind session: only if wire_version >= 6, MongoDB 3.6.x
144
+ #
145
+ def handle_event ( { :call , from } , { :bind_session , cmd } , :no_transaction , % Session { conn: conn , wire_version: wire_version , server_session: % ServerSession { session_id: id } } ) when wire_version >= 6 do
141
146
{ :keep_state_and_data , { :reply , from , { :ok , conn , Keyword . merge ( cmd , lsid: % { id: id } ) } } }
142
147
end
143
- def handle_event ( { :call , from } , { :bind_session , cmd } , :starting_transaction , % Session { conn: conn , server_session: % ServerSession { session_id: id , txn_num: txn_num } , opts: opts } = data ) do
148
+ def handle_event ( { :call , from } , { :bind_session , cmd } , :starting_transaction ,
149
+ % Session { conn: conn ,
150
+ server_session: % ServerSession { session_id: id , txn_num: txn_num } ,
151
+ wire_version: wire_version , opts: opts } = data ) when wire_version >= 6 do
144
152
result = Keyword . merge ( cmd ,
145
153
readConcern: Keyword . get ( opts , :read_concern ) ,
146
154
lsid: % { id: id } ,
@@ -149,13 +157,18 @@ defmodule Mongo.Session do
149
157
autocommit: false ) |> filter_nils ( )
150
158
{ :next_state , :transaction_in_progress , data , { :reply , from , { :ok , conn , result } } }
151
159
end
152
- def handle_event ( { :call , from } , { :bind_session , cmd } , :transaction_in_progress , % Session { conn: conn , server_session: % ServerSession { session_id: id , txn_num: txn_num } } ) do
160
+ def handle_event ( { :call , from } , { :bind_session , cmd } , :transaction_in_progress ,
161
+ % Session { conn: conn , wire_version: wire_version ,
162
+ server_session: % ServerSession { session_id: id , txn_num: txn_num } } ) when wire_version >= 6 do
153
163
result = Keyword . merge ( cmd ,
154
164
lsid: % { id: id } ,
155
165
txnNumber: % BSON.LongNumber { value: txn_num } ,
156
166
autocommit: false )
157
167
{ :keep_state_and_data , { :reply , from , { :ok , conn , result } } }
158
168
end
169
+ def handle_event ( { :call , from } , { :bind_session , cmd } , transaction , % Session { conn: conn } ) when transaction in [ :no_transaction , :starting_transaction , :transaction_in_progress ] do
170
+ { :keep_state_and_data , { :reply , from , { :ok , conn , cmd } } }
171
+ end
159
172
160
173
def handle_event ( { :call , from } , { :commit_transaction } , :transaction_in_progress , data ) do
161
174
{ :next_state , :transaction_committed , data , { :reply , from , run_commit_command ( data ) } }
@@ -172,7 +185,7 @@ defmodule Mongo.Session do
172
185
def handle_event ( { :call , from } , { :end_implicit_session } , _state , % Session { server_session: session_server , implicit: true } ) do
173
186
{ :stop_and_reply , :normal , { :reply , from , { :ok , session_server } } }
174
187
end
175
- def handle_event ( { :call , from } , { :end_implicit_session } , _state , % Session { server_session: session_server , implicit: false } ) do
188
+ def handle_event ( { :call , from } , { :end_implicit_session } , _state , % Session { implicit: false } ) do
176
189
{ :keep_state_and_data , { :reply , from , :noop } }
177
190
end
178
191
0 commit comments