@@ -894,15 +894,6 @@ function selectServers(topology, selector, timeout, start, callback) {
894
894
topology . s . monitorTimers . push ( timer ) ;
895
895
} ) ;
896
896
897
- const descriptionChangedHandler = ( ) => {
898
- // successful iteration, clear the check timer
899
- clearTimeout ( iterationTimer ) ;
900
- topology . s . iterationTimers . splice ( timerIndex , 1 ) ;
901
-
902
- // topology description has changed due to monitoring, reattempt server selection
903
- selectServers ( topology , selector , timeout , start , callback ) ;
904
- } ;
905
-
906
897
const iterationTimer = setTimeout ( ( ) => {
907
898
topology . removeListener ( 'topologyDescriptionChanged' , descriptionChangedHandler ) ;
908
899
callback (
@@ -913,16 +904,25 @@ function selectServers(topology, selector, timeout, start, callback) {
913
904
) ;
914
905
} , timeout - duration ) ;
915
906
907
+ const descriptionChangedHandler = ( ) => {
908
+ // successful iteration, clear the check timer
909
+ removeTimerFrom ( iterationTimer , topology . s . iterationTimers ) ;
910
+ clearTimeout ( iterationTimer ) ;
911
+
912
+ // topology description has changed due to monitoring, reattempt server selection
913
+ selectServers ( topology , selector , timeout , start , callback ) ;
914
+ } ;
915
+
916
916
// track this timer in case we need to clean it up outside this loop
917
- const timerIndex = topology . s . iterationTimers . push ( iterationTimer ) ;
917
+ topology . s . iterationTimers . push ( iterationTimer ) ;
918
918
919
919
topology . once ( 'topologyDescriptionChanged' , descriptionChangedHandler ) ;
920
920
} ;
921
921
922
922
retrySelection ( ) ;
923
923
}
924
924
925
- function createAndConnectServer ( topology , serverDescription ) {
925
+ function createAndConnectServer ( topology , serverDescription , connectDelay ) {
926
926
topology . emit (
927
927
'serverOpening' ,
928
928
new monitoring . ServerOpeningEvent ( topology . s . id , serverDescription . address )
@@ -934,10 +934,45 @@ function createAndConnectServer(topology, serverDescription) {
934
934
server . once ( 'connect' , serverConnectEventHandler ( server , topology ) ) ;
935
935
server . on ( 'descriptionReceived' , topology . serverUpdateHandler . bind ( topology ) ) ;
936
936
server . on ( 'error' , serverErrorEventHandler ( server , topology ) ) ;
937
+
938
+ if ( connectDelay ) {
939
+ const connectTimer = setTimeout ( ( ) => {
940
+ removeTimerFrom ( connectTimer , topology . s . iterationTimers ) ;
941
+ server . connect ( ) ;
942
+ } , connectDelay ) ;
943
+
944
+ topology . s . iterationTimers . push ( connectTimer ) ;
945
+ return server ;
946
+ }
947
+
937
948
server . connect ( ) ;
938
949
return server ;
939
950
}
940
951
952
+ function resetServer ( topology , serverDescription ) {
953
+ if ( ! topology . s . servers . has ( serverDescription . address ) ) {
954
+ return ;
955
+ }
956
+
957
+ // first remove the old server
958
+ const server = topology . s . servers . get ( serverDescription . address ) ;
959
+ destroyServer ( server , topology ) ;
960
+
961
+ // add the new server, and attempt connection after a delay
962
+ const newServer = createAndConnectServer (
963
+ topology ,
964
+ serverDescription ,
965
+ topology . s . heartbeatFrequencyMS
966
+ ) ;
967
+
968
+ topology . s . servers . set ( serverDescription . address , newServer ) ;
969
+ }
970
+
971
+ function removeTimerFrom ( timer , timers ) {
972
+ const idx = timers . findIndex ( t => t === timer ) ;
973
+ timers . splice ( idx , 1 ) ;
974
+ }
975
+
941
976
/**
942
977
* Create `Server` instances for all initially known servers, connect them, and assign
943
978
* them to the passed in `Topology`.
@@ -954,6 +989,15 @@ function connectServers(topology, serverDescriptions) {
954
989
}
955
990
956
991
function updateServers ( topology , incomingServerDescription ) {
992
+ // if the server was reset internally because of an error, we need to replace the
993
+ // `Server` instance for it so we can attempt reconnect.
994
+ //
995
+ // TODO: this logical can change once CMAP is put in place
996
+ if ( incomingServerDescription && incomingServerDescription . error ) {
997
+ resetServer ( topology , incomingServerDescription ) ;
998
+ return ;
999
+ }
1000
+
957
1001
// update the internal server's description
958
1002
if ( incomingServerDescription && topology . s . servers . has ( incomingServerDescription . address ) ) {
959
1003
const server = topology . s . servers . get ( incomingServerDescription . address ) ;
0 commit comments