code: func (s *Serf) handleNodeLeave(n *memberlist.Node) {
  	s.memberLock.Lock()
  	defer s.memberLock.Unlock()
  
  	member, ok := s.members[n.Name]
  	if !ok {
  		// We've never even heard of this node that is supposedly
  		// leaving. Just ignore it completely.
  		return
  	}
  
  	switch member.Status {
  	case StatusLeaving:
  		member.Status = StatusLeft
  		member.leaveTime = time.Now()
  		s.leftMembers = append(s.leftMembers, member)
  	case StatusAlive:
  		member.Status = StatusFailed
  		member.leaveTime = time.Now()
  		s.failedMembers = append(s.failedMembers, member)
  	default:
  		// Unknown state that it was in? Just don't do anything
  		s.logger.Printf("[WARN] serf: Bad state when leave: %d", member.Status)
  		return
  	}
  
  	// Send an event along
  	event := EventMemberLeave
  	eventStr := "EventMemberLeave"
  	if member.Status != StatusLeft {
  		event = EventMemberFailed
  		eventStr = "EventMemberFailed"
  	}
  
  	// Update some metrics
  	metrics.IncrCounter([]string{"serf", "member", member.Status.String()}, 1)
  
  	s.logger.Printf("[INFO] serf: %s: %s %s",
  		eventStr, member.Member.Name, member.Member.Addr)
  	if s.config.EventCh != nil {
  		s.config.EventCh <- MemberEvent{
  			Type:    event,
  			Members: []Member{member.Member},
  		}
  	}
  }
docs: // handleNodeLeave is called when a node leave event is received
  // from memberlist.