@@ -128,8 +128,8 @@ export interface TopologyPrivate {
128128
129129 /** related to srv polling */
130130 srvPoller ?: SrvPoller ;
131- detectTopologyDescriptionChange ? : ( event : TopologyDescriptionChangedEvent ) => void ;
132- handleSrvPolling ? : ( event : SrvPollingEvent ) => void ;
131+ detectShardedTopology : ( event : TopologyDescriptionChangedEvent ) => void ;
132+ detectSrvRecords : ( event : SrvPollingEvent ) => void ;
133133}
134134
135135/** @public */
@@ -319,36 +319,57 @@ export class Topology extends TypedEventEmitter<TopologyEvents> {
319319 clusterTime : undefined ,
320320
321321 // timer management
322- connectionTimers : new Set < NodeJS . Timeout > ( )
322+ connectionTimers : new Set < NodeJS . Timeout > ( ) ,
323+
324+ detectShardedTopology : ev => this . detectShardedTopology ( ev ) ,
325+ detectSrvRecords : ev => this . detectSrvRecords ( ev )
323326 } ;
324327
325328 if ( options . srvHost ) {
326329 this . s . srvPoller =
327- options . srvPoller ||
330+ options . srvPoller ??
328331 new SrvPoller ( {
329332 heartbeatFrequencyMS : this . s . heartbeatFrequencyMS ,
330333 srvHost : options . srvHost
331334 } ) ;
332335
333- this . s . detectTopologyDescriptionChange = ( ev : TopologyDescriptionChangedEvent ) => {
334- const previousType = ev . previousDescription . type ;
335- const newType = ev . newDescription . type ;
336+ this . on ( Topology . TOPOLOGY_DESCRIPTION_CHANGED , this . s . detectShardedTopology ) ;
337+ }
338+ }
336339
337- if ( previousType !== TopologyType . Sharded && newType === TopologyType . Sharded ) {
338- this . s . handleSrvPolling = srvPollingHandler ( this ) ;
339- if ( this . s . srvPoller ) {
340- // TODO(NODE-3269): it looks like there is a bug here, what if this happens twice?
341- this . s . srvPoller . on ( 'srvRecordDiscovery' , this . s . handleSrvPolling ) ;
342- this . s . srvPoller . start ( ) ;
343- }
344- }
345- } ;
340+ private detectShardedTopology ( event : TopologyDescriptionChangedEvent ) {
341+ const previousType = event . previousDescription . type ;
342+ const newType = event . newDescription . type ;
343+
344+ const transitionToSharded =
345+ previousType !== TopologyType . Sharded && newType === TopologyType . Sharded ;
346+ const srvListeners = this . s . srvPoller ?. listeners ( SrvPoller . SRV_RECORD_DISCOVERY ) ;
347+ const listeningToSrvPolling = ! ! srvListeners ?. includes ( this . s . detectSrvRecords ) ;
348+
349+ if ( transitionToSharded && ! listeningToSrvPolling ) {
350+ this . s . srvPoller ?. on ( SrvPoller . SRV_RECORD_DISCOVERY , this . s . detectSrvRecords ) ;
351+ this . s . srvPoller ?. start ( ) ;
352+ }
353+ }
346354
347- this . on ( Topology . TOPOLOGY_DESCRIPTION_CHANGED , this . s . detectTopologyDescriptionChange ) ;
355+ private detectSrvRecords ( ev : SrvPollingEvent ) {
356+ const previousTopologyDescription = this . s . description ;
357+ this . s . description = this . s . description . updateFromSrvPollingEvent ( ev ) ;
358+ if ( this . s . description === previousTopologyDescription ) {
359+ // Nothing changed, so return
360+ return ;
348361 }
349362
350- // NOTE: remove this when NODE-1709 is resolved
351- this . setMaxListeners ( Infinity ) ;
363+ updateServers ( this ) ;
364+
365+ this . emit (
366+ Topology . TOPOLOGY_DESCRIPTION_CHANGED ,
367+ new TopologyDescriptionChangedEvent (
368+ this . s . id ,
369+ previousTopologyDescription ,
370+ this . s . description
371+ )
372+ ) ;
352373 }
353374
354375 /**
@@ -456,20 +477,10 @@ export class Topology extends TypedEventEmitter<TopologyEvents> {
456477
457478 if ( this . s . srvPoller ) {
458479 this . s . srvPoller . stop ( ) ;
459- if ( this . s . handleSrvPolling ) {
460- this . s . srvPoller . removeListener ( 'srvRecordDiscovery' , this . s . handleSrvPolling ) ;
461- delete this . s . handleSrvPolling ;
462- }
480+ this . s . srvPoller . removeListener ( SrvPoller . SRV_RECORD_DISCOVERY , this . s . detectSrvRecords ) ;
463481 }
464482
465- if ( this . s . detectTopologyDescriptionChange ) {
466- // TODO(NODE-3272): This isn't the event that the detectTopologyDescriptionChange event is listening to
467- this . removeListener (
468- Topology . SERVER_DESCRIPTION_CHANGED ,
469- this . s . detectTopologyDescriptionChange
470- ) ;
471- delete this . s . detectTopologyDescriptionChange ;
472- }
483+ this . removeListener ( Topology . TOPOLOGY_DESCRIPTION_CHANGED , this . s . detectShardedTopology ) ;
473484
474485 for ( const session of this . s . sessions ) {
475486 session . endSession ( ) ;
@@ -478,7 +489,7 @@ export class Topology extends TypedEventEmitter<TopologyEvents> {
478489 this . s . sessionPool . endAllPooledSessions ( ( ) => {
479490 eachAsync (
480491 Array . from ( this . s . servers . values ( ) ) ,
481- ( server : Server , cb : Callback ) => destroyServer ( server , this , options , cb ) ,
492+ ( server , cb ) => destroyServer ( server , this , options , cb ) ,
482493 err => {
483494 this . s . servers . clear ( ) ;
484495
@@ -924,31 +935,6 @@ function updateServers(topology: Topology, incomingServerDescription?: ServerDes
924935 }
925936}
926937
927- function srvPollingHandler ( topology : Topology ) {
928- return function handleSrvPolling ( ev : SrvPollingEvent ) {
929- const previousTopologyDescription = topology . s . description ;
930- topology . s . description = topology . s . description . updateFromSrvPollingEvent ( ev ) ;
931- if ( topology . s . description === previousTopologyDescription ) {
932- // Nothing changed, so return
933- return ;
934- }
935-
936- updateServers ( topology ) ;
937-
938- topology . emit (
939- Topology . SERVER_DESCRIPTION_CHANGED ,
940- // TODO(NODE-3272): This server description changed event is emitting a TopologyDescriptionChangeEvent
941- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
942- // @ts -expect-error
943- new TopologyDescriptionChangedEvent (
944- topology . s . id ,
945- previousTopologyDescription ,
946- topology . s . description
947- )
948- ) ;
949- } ;
950- }
951-
952938function drainWaitQueue ( queue : Denque < ServerSelectionRequest > , err ?: AnyError ) {
953939 while ( queue . length ) {
954940 const waitQueueMember = queue . shift ( ) ;
0 commit comments