@@ -5,13 +5,9 @@ const ServerType = require('./common').ServerType;
5
5
const TopologyDescription = require ( './topology_description' ) ;
6
6
const TopologyType = require ( './common' ) . TopologyType ;
7
7
const monitoring = require ( './monitoring' ) ;
8
- const calculateDurationInMs = require ( '../utils' ) . calculateDurationInMs ;
9
- const MongoTimeoutError = require ( '../error' ) . MongoTimeoutError ;
10
8
const Server = require ( './server' ) ;
11
9
const relayEvents = require ( '../utils' ) . relayEvents ;
12
10
const ReadPreference = require ( '../topologies/read_preference' ) ;
13
- const readPreferenceServerSelector = require ( './server_selectors' ) . readPreferenceServerSelector ;
14
- const writableServerSelector = require ( './server_selectors' ) . writableServerSelector ;
15
11
const isRetryableWritesSupported = require ( '../topologies/shared' ) . isRetryableWritesSupported ;
16
12
const CoreCursor = require ( '../cursor' ) . CoreCursor ;
17
13
const deprecate = require ( 'util' ) . deprecate ;
@@ -27,20 +23,19 @@ const SrvPoller = require('./srv_polling').SrvPoller;
27
23
const getMMAPError = require ( '../topologies/shared' ) . getMMAPError ;
28
24
const makeStateMachine = require ( '../utils' ) . makeStateMachine ;
29
25
const eachAsync = require ( '../utils' ) . eachAsync ;
26
+
30
27
const common = require ( './common' ) ;
28
+ const drainTimerQueue = common . drainTimerQueue ;
29
+ const clearAndRemoveTimerFrom = common . clearAndRemoveTimerFrom ;
30
+
31
+ const serverSelection = require ( './server_selection' ) ;
32
+ const readPreferenceServerSelector = serverSelection . readPreferenceServerSelector ;
33
+ const writableServerSelector = serverSelection . writableServerSelector ;
34
+ const selectServers = serverSelection . selectServers ;
31
35
32
36
// Global state
33
37
let globalTopologyCounter = 0 ;
34
38
35
- // Constants
36
- const TOPOLOGY_DEFAULTS = {
37
- useUnifiedTopology : true ,
38
- localThresholdMS : 15 ,
39
- serverSelectionTimeoutMS : 30000 ,
40
- heartbeatFrequencyMS : 10000 ,
41
- minHeartbeatFrequencyMS : 500
42
- } ;
43
-
44
39
// events that we relay to the `Topology`
45
40
const SERVER_RELAY_EVENTS = [
46
41
'serverHeartbeatStarted' ,
@@ -114,7 +109,7 @@ class Topology extends EventEmitter {
114
109
seedlist = parseStringSeedlist ( seedlist ) ;
115
110
}
116
111
117
- options = Object . assign ( { } , TOPOLOGY_DEFAULTS , options ) ;
112
+ options = Object . assign ( { } , common . TOPOLOGY_DEFAULTS , options ) ;
118
113
119
114
const topologyType = topologyTypeFromSeedlist ( seedlist , options ) ;
120
115
const topologyId = globalTopologyCounter ++ ;
@@ -810,115 +805,6 @@ function randomSelection(array) {
810
805
return array [ Math . floor ( Math . random ( ) * array . length ) ] ;
811
806
}
812
807
813
- /**
814
- * Selects servers using the provided selector
815
- *
816
- * @private
817
- * @param {Topology } topology The topology to select servers from
818
- * @param {function } selector The actual predicate used for selecting servers
819
- * @param {Number } timeout The max time we are willing wait for selection
820
- * @param {Number } start A high precision timestamp for the start of the selection process
821
- * @param {function } callback The callback used to convey errors or the resultant servers
822
- */
823
- function selectServers ( topology , selector , timeout , start , callback ) {
824
- const duration = calculateDurationInMs ( start ) ;
825
- if ( duration >= timeout ) {
826
- return callback (
827
- new MongoTimeoutError ( `Server selection timed out after ${ timeout } ms` ) ,
828
- topology . description . error
829
- ) ;
830
- }
831
-
832
- // ensure we are connected
833
- if ( topology . s . state !== STATE_CONNECTED && topology . s . state !== STATE_CONNECTING ) {
834
- topology . connect ( ) ;
835
-
836
- // we want to make sure we're still within the requested timeout window
837
- const failToConnectTimer = setTimeout ( ( ) => {
838
- topology . removeListener ( 'connect' , connectHandler ) ;
839
- callback (
840
- new MongoTimeoutError ( 'Server selection timed out waiting to connect' ) ,
841
- topology . description . error
842
- ) ;
843
- } , timeout - duration ) ;
844
-
845
- const connectHandler = ( ) => {
846
- clearAndRemoveTimerFrom ( failToConnectTimer , topology . s . connectionTimers ) ;
847
- selectServers ( topology , selector , timeout , process . hrtime ( ) , callback ) ;
848
- } ;
849
-
850
- topology . s . connectionTimers . add ( failToConnectTimer ) ;
851
- topology . once ( 'connect' , connectHandler ) ;
852
- return ;
853
- }
854
-
855
- // otherwise, attempt server selection
856
- const serverDescriptions = Array . from ( topology . description . servers . values ( ) ) ;
857
- let descriptions ;
858
-
859
- // support server selection by options with readPreference
860
- if ( typeof selector === 'object' ) {
861
- const readPreference = selector . readPreference
862
- ? selector . readPreference
863
- : ReadPreference . primary ;
864
-
865
- selector = readPreferenceServerSelector ( readPreference ) ;
866
- }
867
-
868
- try {
869
- descriptions = selector
870
- ? selector ( topology . description , serverDescriptions )
871
- : serverDescriptions ;
872
- } catch ( e ) {
873
- return callback ( e , null ) ;
874
- }
875
-
876
- if ( descriptions . length ) {
877
- const servers = descriptions . map ( description => topology . s . servers . get ( description . address ) ) ;
878
- return callback ( null , servers ) ;
879
- }
880
-
881
- const retrySelection = ( ) => {
882
- // clear all existing monitor timers
883
- drainTimerQueue ( topology . s . monitorTimers ) ;
884
-
885
- // ensure all server monitors attempt monitoring soon
886
- topology . s . servers . forEach ( server => {
887
- const timer = setTimeout (
888
- ( ) => server . monitor ( { heartbeatFrequencyMS : topology . description . heartbeatFrequencyMS } ) ,
889
- TOPOLOGY_DEFAULTS . minHeartbeatFrequencyMS
890
- ) ;
891
-
892
- topology . s . monitorTimers . add ( timer ) ;
893
- } ) ;
894
-
895
- const iterationTimer = setTimeout ( ( ) => {
896
- topology . removeListener ( 'topologyDescriptionChanged' , descriptionChangedHandler ) ;
897
- callback (
898
- new MongoTimeoutError (
899
- `Server selection timed out after ${ timeout } ms` ,
900
- topology . description . error
901
- )
902
- ) ;
903
- } , timeout - duration ) ;
904
-
905
- const descriptionChangedHandler = ( ) => {
906
- // successful iteration, clear the check timer
907
- clearAndRemoveTimerFrom ( iterationTimer , topology . s . iterationTimers ) ;
908
-
909
- // topology description has changed due to monitoring, reattempt server selection
910
- selectServers ( topology , selector , timeout , start , callback ) ;
911
- } ;
912
-
913
- // track this timer in case we need to clean it up outside this loop
914
- topology . s . iterationTimers . add ( iterationTimer ) ;
915
-
916
- topology . once ( 'topologyDescriptionChanged' , descriptionChangedHandler ) ;
917
- } ;
918
-
919
- retrySelection ( ) ;
920
- }
921
-
922
808
function createAndConnectServer ( topology , serverDescription , connectDelay ) {
923
809
topology . emit (
924
810
'serverOpening' ,
@@ -965,16 +851,6 @@ function resetServer(topology, serverDescription) {
965
851
topology . s . servers . set ( serverDescription . address , newServer ) ;
966
852
}
967
853
968
- function drainTimerQueue ( queue ) {
969
- queue . forEach ( clearTimeout ) ;
970
- queue . clear ( ) ;
971
- }
972
-
973
- function clearAndRemoveTimerFrom ( timer , timers ) {
974
- clearTimeout ( timer ) ;
975
- return timers . delete ( timer ) ;
976
- }
977
-
978
854
/**
979
855
* Create `Server` instances for all initially known servers, connect them, and assign
980
856
* them to the passed in `Topology`.
0 commit comments