code: func (c *MemberlistManager) clusterStats() {
  	primReady := 0
  	primNotReady := 0
  	secReady := 0
  	secNotReady := 0
  	queryReady := 0
  	queryNotReady := 0
  	partitions := make(map[int32]int)
  	for _, p := range c.members {
  		if p.Primary {
  			if p.IsReady() {
  				primReady++
  			} else {
  				primNotReady++
  			}
  		} else if p.Mode != ModeQuery {
  			if p.IsReady() {
  				secReady++
  			} else {
  				secNotReady++
  			}
  		} else {
  			if p.IsReady() {
  				queryReady++
  			} else {
  				queryNotReady++
  			}
  		}
  		for _, partition := range p.Partitions {
  			partitions[partition]++
  		}
  	}
  
  	totalPrimaryReady.Set(primReady)
  	totalPrimaryNotReady.Set(primNotReady)
  	totalSecondaryReady.Set(secReady)
  	totalSecondaryNotReady.Set(secNotReady)
  	totalQueryReady.Set(queryReady)
  	totalQueryNotReady.Set(queryNotReady)
  
  	totalPartitions.Set(len(partitions))
  }
docs: // report the cluster stats every time there is a change to the cluster state.
  // it is assumed that the lock is acquired before calling this method.