code: func (m *Memberlist) Shutdown() error {
  	m.shutdownLock.Lock()
  	defer m.shutdownLock.Unlock()
  
  	if m.hasShutdown() {
  		return nil
  	}
  
  	// Shut down the transport first, which should block until it's
  	// completely torn down. If we kill the memberlist-side handlers
  	// those I/O handlers might get stuck.
  	if err := m.transport.Shutdown(); err != nil {
  		m.logger.Printf("[ERR] Failed to shutdown transport: %v", err)
  	}
  
  	// Now tear down everything else.
  	atomic.StoreInt32(&m.shutdown, 1)
  	close(m.shutdownCh)
  	m.deschedule()
  	return nil
  }
docs: // Shutdown will stop any background maintanence of network activity
  // for this memberlist, causing it to appear "dead". A leave message
  // will not be broadcasted prior, so the cluster being left will have
  // to detect this node's shutdown using probing. If you wish to more
  // gracefully exit the cluster, call Leave prior to shutting down.
  //
  // This method is safe to call multiple times.