// A server has left the cluster, so tombstone all of its records
165978
func (state *ServicesState) ExpireServer(hostname string) {
	if !state.HasServer(hostname) || len(state.Servers[hostname].Services) == 0 {
		log.Infof("No records to expire for %s", hostname)
		return
	}

	hasLiveServices := false
	for _, svc := range state.Servers[hostname].Services {
		if !svc.IsTombstone() {
			hasLiveServices = true
			break
		}
	}

	if !hasLiveServices {
		log.Infof("No records to expire for %s (no live services)", hostname)
		return
	}

	log.Infof("Expiring %s", hostname)

	var tombstones []service.Service

	for _, svc := range state.Servers[hostname].Services {
		previousStatus := svc.Status
		state.ServiceChanged(svc, previousStatus, svc.Updated)
		svc.Tombstone()
		tombstones = append(tombstones, *svc)
	}

	if len(tombstones) < 1 {
		log.Warn("Tried to announce a zero length list of tombstones")
		return
	}

	state.SendServices(
		tombstones,
		director.NewTimedLooper(TOMBSTONE_COUNT, state.tombstoneRetransmit, nil),
	)
}
209886
func (s *Server) Stop() {
	s.quitOnce.Do(func() {
		close(s.quit)
	})

	defer func() {
		s.serveWG.Wait()
		s.doneOnce.Do(func() {
			close(s.done)
		})
	}()

	s.channelzRemoveOnce.Do(func() {
		if channelz.IsOn() {
			channelz.RemoveEntry(s.channelzID)
		}
	})

	s.mu.Lock()
	listeners := s.lis
	s.lis = nil
	st := s.conns
	s.conns = nil
	// interrupt GracefulStop if Stop and GracefulStop are called concurrently.
	s.cv.Broadcast()
	s.mu.Unlock()

	for lis := range listeners {
		lis.Close()
	}
	for c := range st {
		c.Close()
	}

	s.mu.Lock()
	if s.events != nil {
		s.events.Finish()
		s.events = nil
	}
	s.mu.Unlock()
}
207812
func (srv *Server) Close() bool {
	if !atomic.CompareAndSwapInt32(&srv.closed, 0, 1) {
		return false
	}

	// immediately closes all connection.
	if srv.KillTimeOut == 0 {
		srv.Server.Close()

		srv.mu.Lock()
		defer srv.mu.Unlock()
		srv.closeDoneChanLocked()
		return true
	}

	// graceful shutdown
	go func() {
		ctx, cancel := context.WithTimeout(context.Background(), srv.KillTimeOut)
		defer cancel()
		srv.Shutdown(ctx)

		srv.mu.Lock()
		defer srv.mu.Unlock()
		srv.closeDoneChanLocked()
	}()

	return true
}
1220650
func (c *Cluster) Cleanup() {
	c.controlMutex.Lock()
	defer c.controlMutex.Unlock()

	c.mu.Lock()
	node := c.nr
	if node == nil {
		c.mu.Unlock()
		return
	}
	state := c.currentNodeState()
	c.mu.Unlock()

	if state.IsActiveManager() {
		active, reachable, unreachable, err := managerStats(state.controlClient, state.NodeID())
		if err == nil {
			singlenode := active && isLastManager(reachable, unreachable)
			if active && !singlenode && removingManagerCausesLossOfQuorum(reachable, unreachable) {
				logrus.Errorf("Leaving cluster with %v managers left out of %v. Raft quorum will be lost.", reachable-1, reachable+unreachable)
			}
		}
	}

	if err := node.Stop(); err != nil {
		logrus.Errorf("failed to shut down cluster node: %v", err)
		signal.DumpStacks("")
	}

	c.mu.Lock()
	c.nr = nil
	c.mu.Unlock()
}
1334078
func (c *cluster) IsCleanedOut(ctx context.Context, serverID string) (bool, error) {
	r, err := c.NumberOfServers(ctx)
	if err != nil {
		return false, WithStack(err)
	}
	for _, id := range r.CleanedServerIDs {
		if id == serverID {
			return true, nil
		}
	}
	return false, nil
}
383432
func (i *Instance) SaveServer(s Server, ln net.Listener) {
	i.servers = append(i.servers, ServerListener{server: s, listener: ln})
}
1087827
func (s *Server) Close(ctx context.Context) error {
	return s.Shutdown(ctx)
}
1025854
func (c *client) Cluster(ctx context.Context) (Cluster, error) {
	role, err := c.ServerRole(ctx)
	if err != nil {
		return nil, WithStack(err)
	}
	if role == ServerRoleSingle || role == ServerRoleSingleActive || role == ServerRoleSinglePassive {
		// Standalone server, this is wrong
		return nil, WithStack(newArangoError(412, 0, "Cluster expected, found SINGLE server"))
	}
	cl, err := newCluster(c.conn)
	if err != nil {
		return nil, WithStack(err)
	}
	return cl, nil
}
685434
func (d *driver) Leave(nid, eid string) error {
	network, err := d.getNetwork(nid)
	if err != nil {
		return types.InternalMaskableErrorf("%s", err)
	}

	// Ensure that the endpoint exists
	endpoint, err := network.getEndpoint(eid)
	if err != nil {
		return err
	}

	err = hcsshim.HotDetachEndpoint(endpoint.sandboxID, endpoint.profileID)
	if err != nil {
		// If container doesn't exists in hcs, do not throw error for hot add/remove
		if err != hcsshim.ErrComputeSystemDoesNotExist {
			return err
		}
	}
	return nil
}
51651
func (s *SyslogCollector) Exit() error {
	s.server.Shutdown()
	s.lre.Close()
	s.lro.Close()
	return nil
}
78262
func (a *Autopilot) serverHealthLoop() {
	defer a.waitGroup.Done()

	// Monitor server health until shutdown
	ticker := time.NewTicker(a.healthInterval)
	defer ticker.Stop()

	for {
		select {
		case <-a.shutdownCh:
			return
		case <-ticker.C:
			if err := a.updateClusterHealth(); err != nil {
				a.logger.Printf("[ERR] autopilot: Error updating cluster health: %s", err)
			}
		}
	}
}
446549
func (s Server) Close() error {
	if s.codec != nil {
		return s.codec.Close()
	}
	return s.rwc.Close()
}
1278235
func (s *Server) leave(roomName string, connID string) (left bool) {
	///THINK: we could add locks to its room but we still use the lock for the whole rooms or we can just do what we do with connections
	// I will think about it on the next revision, so far we use the locks only for rooms so we are ok...
	if s.rooms[roomName] != nil {
		for i := range s.rooms[roomName] {
			if s.rooms[roomName][i] == connID {
				s.rooms[roomName] = append(s.rooms[roomName][:i], s.rooms[roomName][i+1:]...)
				left = true
				break
			}
		}
		if len(s.rooms[roomName]) == 0 { // if room is empty then delete it
			delete(s.rooms, roomName)
		}
	}

	if left {
		// fire the on room leave connection's listeners,
		// the existence check is not necessary here.
		if c, ok := s.getConnection(connID); ok {
			c.fireOnLeave(roomName)
		}
	}
	return
}
432956
func (server *Server) Shutdown() error {
	if server.cancel != nil {
		server.cancel()
	}
	if server.listener != nil {
		return server.listener.Close()
	}
	// server wasnt even started
	return nil
}
197098
func (c *Client) cleanup() {
	// check if not cleanly connected and will is present
	if atomic.LoadUint32(&c.state) == clientConnected && c.will != nil {
		// publish message
		err := c.backend.Publish(c, c.will, nil)
		if err != nil {
			c.backend.Log(BackendError, c, nil, nil, err)
		}

		c.backend.Log(MessagePublished, c, nil, c.will, nil)
	}

	// remove client from the queue
	if atomic.LoadUint32(&c.state) >= clientConnected {
		err := c.backend.Terminate(c)
		if err != nil {
			c.backend.Log(BackendError, c, nil, nil, err)
		}
	}

	c.backend.Log(LostConnection, c, nil, nil, nil)
}
718113
func (c *RPCClient) Leave() error {
	header := requestHeader{
		Command: leaveCommand,
		Seq:     c.getSeq(),
	}
	return c.genericRPC(&header, nil, nil)
}
553349
func (s *Server) Close() error {
	// Notify goroutines to stop.
	close(s.closing)
	s.wg.Wait()

	var errh error
	var errc error
	if s.cluster != nil {
		errc = s.cluster.close()
	}
	if s.holder != nil {
		errh = s.holder.Close()
	}
	// prefer to return holder error over cluster
	// error. This order is somewhat arbitrary. It would be better if we had
	// some way to combine all the errors, but probably not important enough to
	// warrant the extra complexity.
	if errh != nil {
		return errors.Wrap(errh, "closing holder")
	}
	return errors.Wrap(errc, "closing cluster")
}