func (c *Client) Shutdown() error {
	c.logger.Printf("[INFO] consul: shutting down client")
	c.shutdownLock.Lock()
	defer c.shutdownLock.Unlock()
	if c.shutdown {
		return nil
	}
	c.shutdown = true
	close(c.shutdownCh)
	if c.serf != nil {
		c.serf.Shutdown()
	}
	c.connPool.Shutdown()
	return nil
}
Shutdown is used to shutdown the client
package consul
import (
	"crypto/tls"
	"fmt"
	"log"
	"math/rand"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"sync"
	"time"
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/hashicorp/consul/consul/structs"
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/hashicorp/serf/serf"
)
const (
	clientRPCCache = 30 * time.Second
	clientMaxStreams = 32
)
type Interface interface {
	RPC(method string, args interface{}, reply interface{}) error
	LANMembers() []serf.Member
	LocalMember() serf.Member
}
type Client struct {
	config *Config
	connPool *ConnPool
	consuls    []*serverParts
	consulLock sync.RWMutex
	eventCh chan serf.Event
	lastServer  *serverParts
	lastRPCTime time.Time
	logger *log.Logger
	serf *serf.Serf
	shutdown     bool
	shutdownCh   chan struct{}
	shutdownLock sync.Mutex
}
func NewClient(config *Config) (*Client, error) {
	if err := config.CheckVersion(); err != nil {
		return nil, err
	}
	if config.DataDir == "" {
		return nil, fmt.Errorf("Config must provide a DataDir")
	}
	if err := config.CheckACL(); err != nil {
		return nil, err
	}
	if config.LogOutput == nil {
		config.LogOutput = os.Stderr
	}
	var tlsConfig *tls.Config
	var err error
	if tlsConfig, err = config.tlsConfig().OutgoingTLSConfig(); err != nil {
		return nil, err
	}
	logger := log.New(config.LogOutput, "", log.LstdFlags)
	c := &Client{
		config:     config,
		connPool:   NewPool(config.LogOutput, clientRPCCache, clientMaxStreams, tlsConfig),
		eventCh:    make(chan serf.Event, 256),
		logger:     logger,
		shutdownCh: make(chan struct{}),
	}
	go c.lanEventHandler()
	c.serf, err = c.setupSerf(config.SerfLANConfig,
		c.eventCh, serfLANSnapshot)
	if err != nil {
		c.Shutdown()
		return nil, fmt.Errorf("Failed to start lan serf: %v", err)
	}
	return c, nil
}
func (c *Client) setupSerf(conf *serf.Config, ch chan serf.Event, path string) (*serf.Serf, error) {
	conf.Init()
	conf.NodeName = c.config.NodeName
	conf.Tags["role"] = "node"
	conf.Tags["dc"] = c.config.Datacenter
	conf.Tags["vsn"] = fmt.Sprintf("%d", c.config.ProtocolVersion)
	conf.Tags["vsn_min"] = fmt.Sprintf("%d", ProtocolVersionMin)
	conf.Tags["vsn_max"] = fmt.Sprintf("%d", ProtocolVersionMax)
	conf.Tags["build"] = c.config.Build
	conf.MemberlistConfig.LogOutput = c.config.LogOutput
	conf.LogOutput = c.config.LogOutput
	conf.EventCh = ch
	conf.SnapshotPath = filepath.Join(c.config.DataDir, path)
	conf.ProtocolVersion = protocolVersionMap[c.config.ProtocolVersion]
	conf.RejoinAfterLeave = c.config.RejoinAfterLeave
	conf.Merge = &lanMergeDelegate{logger: c.logger, dc: c.config.Datacenter}
	if err := ensurePath(conf.SnapshotPath, false); err != nil {
		return nil, err
	}
	return serf.Create(conf)
}