@@ -12,7 +12,7 @@ use self::server::Server;
1212use super :: TopologyDescription ;
1313use crate :: {
1414 cmap:: { Command , Connection } ,
15- error:: Result ,
15+ error:: { Error , Result } ,
1616 options:: { ClientOptions , StreamAddress } ,
1717 sdam:: {
1818 description:: server:: { ServerDescription , ServerType } ,
@@ -175,6 +175,54 @@ impl Topology {
175175 }
176176}
177177
178+ pub ( crate ) fn handle_pre_handshake_error (
179+ error : Error ,
180+ address : StreamAddress ,
181+ topology : Arc < RwLock < Topology > > ,
182+ ) {
183+ if error. is_network_error ( ) {
184+ mark_server_as_unknown ( error, address, topology) ;
185+ }
186+ }
187+
188+ pub ( crate ) fn handle_post_handshake_error (
189+ error : Error ,
190+ conn : Connection ,
191+ server : Arc < Server > ,
192+ topology : Arc < RwLock < Topology > > ,
193+ ) {
194+ // If we encounter certain errors, we must update the topology as per the
195+ // SDAM spec.
196+ if error. is_non_timeout_network_error ( ) {
197+ mark_server_as_unknown ( error, server. address . clone ( ) , topology) ;
198+ server. clear_connection_pool ( ) ;
199+ } else if error. is_recovering ( ) || error. is_not_master ( ) {
200+ mark_server_as_unknown ( error. clone ( ) , server. address . clone ( ) , topology) ;
201+
202+ // For "node is recovering" or "not master" errors, we must request a
203+ // topology check.
204+ server. request_topology_check ( ) ;
205+
206+ let wire_version = conn
207+ . stream_description ( )
208+ . map ( |sd| sd. max_wire_version )
209+ . ok ( )
210+ . and_then ( std:: convert:: identity)
211+ . unwrap_or ( 0 ) ;
212+
213+ // in 4.2+, we only clear connection pool if we've received a
214+ // "node is shutting down" error. Otherwise, we always clear the pool.
215+ if wire_version < 8 || error. is_shutting_down ( ) {
216+ server. clear_connection_pool ( ) ;
217+ }
218+ }
219+ }
220+
221+ fn mark_server_as_unknown ( error : Error , address : StreamAddress , topology : Arc < RwLock < Topology > > ) {
222+ let description = ServerDescription :: new ( address, Some ( Err ( error) ) ) ;
223+ update_topology ( topology, description) ;
224+ }
225+
178226/// Updates the provided topology in a minimally contentious way by cloning first.
179227pub ( crate ) fn update_topology (
180228 topology : Arc < RwLock < Topology > > ,
0 commit comments