code: func (m *Memberlist) deadNode(d *dead) {
  	m.nodeLock.Lock()
  	defer m.nodeLock.Unlock()
  	state, ok := m.nodeMap[d.Node]
  
  	// If we've never heard about this node before, ignore it
  	if !ok {
  		return
  	}
  
  	// Ignore old incarnation numbers
  	if d.Incarnation < state.Incarnation {
  		return
  	}
  
  	// Clear out any suspicion timer that may be in effect.
  	delete(m.nodeTimers, d.Node)
  
  	// Ignore if node is already dead
  	if state.State == stateDead {
  		return
  	}
  
  	// Check if this is us
  	if state.Name == m.config.Name {
  		// If we are not leaving we need to refute
  		if !m.hasLeft() {
  			m.refute(state, d.Incarnation)
  			m.logger.Printf("[WARN] memberlist: Refuting a dead message (from: %s)", d.From)
  			return // Do not mark ourself dead
  		}
  
  		// If we are leaving, we broadcast and wait
  		m.encodeBroadcastNotify(d.Node, deadMsg, d, m.leaveBroadcast)
  	} else {
  		m.encodeAndBroadcast(d.Node, deadMsg, d)
  	}
  
  	// Update metrics
  	metrics.IncrCounter([]string{"memberlist", "msg", "dead"}, 1)
  
  	// Update the state
  	state.Incarnation = d.Incarnation
  	state.State = stateDead
  	state.StateChange = time.Now()
  
  	// Notify of death
  	if m.config.Events != nil {
  		m.config.Events.NotifyLeave(&state.Node)
  	}
  }
docs: // deadNode is invoked by the network layer when we get a message
  // about a dead node