code: func (c *cluster) receiveNodeState(nodeID string, state string) error {
  	c.mu.Lock()
  	defer c.mu.Unlock()
  	if !c.unprotectedIsCoordinator() {
  		return nil
  	}
  
  	c.Topology.mu.Lock()
  	changed := false
  	if c.Topology.nodeStates[nodeID] != state {
  		changed = true
  		c.Topology.nodeStates[nodeID] = state
  		for i, n := range c.nodes {
  			if n.ID == nodeID {
  				c.nodes[i].State = state
  			}
  		}
  	}
  	c.Topology.mu.Unlock()
  	c.logger.Printf("received state %s (%s)", state, nodeID)
  
  	if changed {
  		return c.unprotectedSetStateAndBroadcast(c.determineClusterState())
  	}
  	return nil
  }
docs: // receiveNodeState sets node state in Topology in order for the
  // Coordinator to keep track of, during startup, which nodes have
  // finished opening their Holder.