func (cluster *mongoCluster) syncServersLoop() {
	for {
		debugf("SYNC Cluster %p is starting a sync loop iteration.", cluster)

		cluster.Lock()
		if cluster.references == 0 {
			cluster.Unlock()
			break
		}
		cluster.references++ // Keep alive while syncing.
		direct := cluster.direct
		cluster.Unlock()

		cluster.syncServersIteration(direct)

		// We just synchronized, so consume any outstanding requests.
		select {
		case <-cluster.sync:
		default:
		}

		cluster.Release()

		// Hold off before allowing another sync. No point in
		// burning CPU looking for down servers.
		if !cluster.failFast {
			time.Sleep(syncShortDelay)
		}

		cluster.Lock()
		if cluster.references == 0 {
			cluster.Unlock()
			break
		}
		cluster.syncCount++
		// Poke all waiters so they have a chance to timeout or
		// restart syncing if they wish to.
		cluster.serverSynced.Broadcast()
		// Check if we have to restart immediately either way.
		restart := !direct && cluster.masters.Empty() || cluster.servers.Empty()
		cluster.Unlock()

		if restart {
			log("SYNC No masters found. Will synchronize again.")
			time.Sleep(syncShortDelay)
			continue
		}

		debugf("SYNC Cluster %p waiting for next requested or scheduled sync.", cluster)

		// Hold off until somebody explicitly requests a synchronization
		// or it's time to check for a cluster topology change again.
		select {
		case <-cluster.sync:
		case <-time.After(syncServersDelay):
		}
	}
	debugf("SYNC Cluster %p is stopping its sync loop.", cluster)
}
func (cluster *mongoCluster) syncServersLoop() {
	for {
		debugf("SYNC Cluster %p is starting a sync loop iteration.", cluster)

		cluster.Lock()
		if cluster.references == 0 {
			cluster.Unlock()
			break
		}
		cluster.references++ 
		direct := cluster.direct
		cluster.Unlock()

		cluster.syncServersIteration(direct)

		
		select {
		case <-cluster.sync:
		default:
		}

		cluster.Release()

		
		
		if !cluster.failFast {
			time.Sleep(syncShortDelay)
		}

		cluster.Lock()
		if cluster.references == 0 {
			cluster.Unlock()
			break
		}
		cluster.syncCount++
		
		
		cluster.serverSynced.Broadcast()
		
		restart := !direct && cluster.masters.Empty() || cluster.servers.Empty()
		cluster.Unlock()

		if restart {
			log("SYNC No masters found. Will synchronize again.")
			time.Sleep(syncShortDelay)
			continue
		}

		debugf("SYNC Cluster %p waiting for next requested or scheduled sync.", cluster)

		
		
		select {
		case <-cluster.sync:
		case <-time.After(syncServersDelay):
		}
	}
	debugf("SYNC Cluster %p is stopping its sync loop.", cluster)
}
func ( cluster * mongoCluster ) syncServersLoop ( ) { for { debugf ( " " , cluster ) cluster . Lock ( ) if cluster . references == 0 { cluster . Unlock ( ) break } cluster . references ++ // Keep alive while syncing. direct := cluster . direct cluster . Unlock ( ) cluster . syncServersIteration ( direct ) // We just synchronized, so consume any outstanding requests. select { case <- cluster . sync : default : } cluster . Release ( ) // Hold off before allowing another sync. No point in // burning CPU looking for down servers. if ! cluster . failFast { time . Sleep ( syncShortDelay ) } cluster . Lock ( ) if cluster . references == 0 { cluster . Unlock ( ) break } cluster . syncCount ++ // Poke all waiters so they have a chance to timeout or // restart syncing if they wish to. cluster . serverSynced . Broadcast ( ) // Check if we have to restart immediately either way. restart := ! direct && cluster . masters . Empty ( ) || cluster . servers . Empty ( ) cluster . Unlock ( ) if restart { log ( " " ) time . Sleep ( syncShortDelay ) continue } debugf ( " " , cluster ) // Hold off until somebody explicitly requests a synchronization // or it's time to check for a cluster topology change again. select { case <- cluster . sync : case <- time . After ( syncServersDelay ) : } } debugf ( " " , cluster ) }
// syncServersLoop loops while the cluster is alive to keep its idea of
// the server topology up-to-date. It must be called just once from
// newCluster.  The loop iterates once syncServersDelay has passed, or
// if somebody injects a value into the cluster.sync channel to force a
// synchronization.  A loop iteration will contact all servers in
// parallel, ask them about known peers and their own role within the
// cluster, and then attempt to do the same with all the peers
// retrieved.
syncServersLoop loops while the cluster is alive to keep its idea of the server topology up - to - date . It must be called just once from newCluster . The loop iterates once syncServersDelay has passed or if somebody injects a value into the cluster . sync channel to force a synchronization . A loop iteration will contact all servers in parallel ask them about known peers and their own role within the cluster and then attempt to do the same with all the peers retrieved .