@@ -52,6 +52,8 @@ defmodule Mongo do
52
52
import Mongo.Utils
53
53
import Mongo.WriteConcern
54
54
55
+ require Logger
56
+
55
57
use Bitwise
56
58
use Mongo.Messages
57
59
@@ -409,20 +411,24 @@ defmodule Mongo do
409
411
opts = Mongo . retryable_reads ( opts )
410
412
411
413
with { :ok , session } <- Session . start_implicit_session ( topology_pid , :read , opts ) ,
412
- result <- exec_command_session ( topology_pid , session , cmd , opts ) ,
414
+ result <- exec_command_session ( session , cmd , opts ) ,
413
415
:ok <- Session . end_implict_session ( topology_pid , session ) do
414
416
case result do
415
417
{ :error , error } ->
416
- case Error . should_retry_read ( error , cmd , opts ) do
417
- true -> issue_command ( topology_pid , cmd , :read , Keyword . put ( opts , :read_counter , 2 ) )
418
- false -> { :error , error }
418
+
419
+ cond do
420
+ Error . not_writable_primary_or_recovering? ( error , opts ) ->
421
+ ## in case of explicity
422
+ issue_command ( topology_pid , cmd , :read , Keyword . put ( opts , :retry_counter , 2 ) )
423
+
424
+ Error . should_retry_read ( error , cmd , opts ) ->
425
+ issue_command ( topology_pid , cmd , :read , Keyword . put ( opts , :read_counter , 2 ) )
426
+
427
+ true ->
428
+ { :error , error }
419
429
end
420
430
_other -> result
421
431
end
422
- else
423
- { :new_connection , _server } ->
424
- :timer . sleep ( 1000 )
425
- issue_command ( topology_pid , cmd , :read , opts )
426
432
end
427
433
end
428
434
def issue_command ( topology_pid , cmd , :write , opts ) do
@@ -431,13 +437,27 @@ defmodule Mongo do
431
437
opts = Mongo . retryable_writes ( opts , acknowledged? ( cmd [ :writeConcerns ] ) )
432
438
433
439
with { :ok , session } <- Session . start_implicit_session ( topology_pid , :write , opts ) ,
434
- result <- exec_command_session ( topology_pid , session , cmd , opts ) ,
440
+ result <- exec_command_session ( session , cmd , opts ) ,
435
441
:ok <- Session . end_implict_session ( topology_pid , session ) do
436
- result
437
- else
438
- { :new_connection , _server } ->
439
- :timer . sleep ( 1000 )
440
- issue_command ( topology_pid , cmd , :write , opts )
442
+
443
+ case result do
444
+ { :error , error } ->
445
+ cond do
446
+ Error . not_writable_primary_or_recovering? ( error , opts ) ->
447
+ ## in case of explicity
448
+ issue_command ( topology_pid , cmd , :read , Keyword . put ( opts , :retry_counter , 2 ) )
449
+
450
+ Error . should_retry_write ( error , cmd , opts ) ->
451
+ issue_command ( topology_pid , cmd , :write , Keyword . put ( opts , :write_counter , 2 ) )
452
+
453
+ true ->
454
+ { :error , error }
455
+ end
456
+
457
+ result ->
458
+ result
459
+ end
460
+
441
461
end
442
462
end
443
463
@@ -724,31 +744,23 @@ defmodule Mongo do
724
744
end
725
745
726
746
@ doc false
727
- @ spec exec_command_session ( GenServer . server , GenServer . server , BSON . document , Keyword . t ) :: { :ok , BSON . document | nil } | { :error , Mongo.Error . t }
728
- def exec_command_session ( topology_pid , session , cmd , opts ) do
729
- with { :ok , conn , new_cmd , address } <- Session . bind_session ( session , cmd ) ,
747
+ @ spec exec_command_session ( GenServer . server , BSON . document , Keyword . t ) :: { :ok , BSON . document | nil } | { :error , Mongo.Error . t }
748
+ def exec_command_session ( session , cmd , opts ) do
749
+ with { :ok , conn , new_cmd } <- Session . bind_session ( session , cmd ) ,
730
750
{ :ok , _cmd , { doc , event } } <- DBConnection . execute ( conn , % Query { action: :command } , [ new_cmd ] , defaults ( opts ) ) ,
731
751
doc <- Session . update_session ( session , doc , opts ) ,
732
- { :ok , doc } <- check_for_error ( doc , event , address ) do
752
+ { :ok , doc } <- check_for_error ( doc , event ) do
733
753
{ :ok , doc }
734
- else
754
+ else
735
755
{ :error , error } ->
736
- ## todo update Topology
737
- IO . inspect ( error )
738
- if error . not_master_or_recovering do
739
- IO . inspect ( "ok" )
740
- server_description = Mongo.ServerDescription . from_is_master_error ( error . address , error )
741
- GenServer . cast ( topology_pid , { :server_description , server_description } )
742
- end
743
- #require IEx; IEx.pry
744
- #:debugger.start()
745
- case Error . should_retry_write ( error , cmd , opts ) do
746
- true ->
747
- with :ok <- Session . select_server ( session , opts ) do
748
- exec_command_session ( topology_pid , session , cmd , Keyword . put ( opts , :write_counter , 2 ) )
749
- end
750
- false -> { :error , error }
756
+ case Error . not_writable_primary_or_recovering? ( error , opts ) do
757
+ true ->
758
+ Session . mark_server_unknown ( session )
759
+ { :error , error }
760
+ false ->
761
+ { :error , error }
751
762
end
763
+
752
764
end
753
765
754
766
end
@@ -757,13 +769,13 @@ defmodule Mongo do
757
769
@ spec exec_command ( GenServer . server , BSON . document , Keyword . t ) :: { :ok , BSON . document | nil } | { :error , Mongo.Error . t }
758
770
def exec_command ( conn , cmd , opts ) do
759
771
with { :ok , _cmd , { doc , event } } <- DBConnection . execute ( conn , % Query { action: :command } , [ cmd ] , defaults ( opts ) ) ,
760
- { :ok , doc } <- check_for_error ( doc , event , conn ) do
772
+ { :ok , doc } <- check_for_error ( doc , event ) do
761
773
{ :ok , doc }
762
774
end
763
775
764
776
end
765
777
766
- defp check_for_error ( % { "ok" => ok } = response , { event , duration } , conn ) when ok == 1 do
778
+ defp check_for_error ( % { "ok" => ok } = response , { event , duration } ) when ok == 1 do
767
779
Events . notify ( % CommandSucceededEvent {
768
780
reply: response ,
769
781
duration: duration ,
@@ -774,9 +786,9 @@ defmodule Mongo do
774
786
} , :commands )
775
787
{ :ok , response }
776
788
end
777
- defp check_for_error ( doc , { event , duration } , address ) do
789
+ defp check_for_error ( doc , { event , duration } ) do
778
790
779
- error = Mongo.Error . exception ( doc , address )
791
+ error = Mongo.Error . exception ( doc )
780
792
781
793
Events . notify ( % CommandFailedEvent {
782
794
failure: error ,
0 commit comments