func (h *thriftClientImpl) GetControllerClient() (controller.TChanController, error) {
	hostInfo, err := h.rpm.FindHostForKey(ControllerServiceName, ControllerServiceName)
	if err != nil {
		h.logger.WithFields(bark.Fields{TagErr: err}).Error("getControllerClient - Failed to find controller host")
		return nil, err
	}
	var currentClient controller.TChanController
	h.cClient.lk.RLock()
	if hostInfo.Addr == h.cClient.currentHostAddr {
		currentClient = h.cClient.currentClient
	}
	h.cClient.lk.RUnlock()
	if currentClient == nil {
		h.cClient.lk.Lock()
		currentClient = h.cClient.currentClient
		if currentClient == nil || hostInfo.Addr != h.cClient.currentHostAddr {
			extClient := thrift.NewClient(h.ch, ControllerServiceName, &thrift.ClientOptions{
				HostPort: hostInfo.Addr,
			})
			currentClient = controller.NewTChanControllerClient(extClient)
			h.cClient.currentClient = currentClient
			h.cClient.currentHostAddr = hostInfo.Addr
		}
		h.cClient.lk.Unlock()
	}
	return currentClient, nil
}
GetControllerClient returns the thrift client for ControllerHost
package common
import (
	"fmt"
	"sync"
	"github.com/uber-common/bark"
	"github.com/uber/cherami-thrift/.generated/go/admin"
	"github.com/uber/cherami-thrift/.generated/go/cherami"
	"github.com/uber/cherami-thrift/.generated/go/controller"
	"github.com/uber/cherami-thrift/.generated/go/replicator"
	"github.com/uber/cherami-thrift/.generated/go/store"
	tchannel "github.com/uber/tchannel-go"
	"github.com/uber/tchannel-go/thrift"
)
type (
	ClientFactory interface {
		GetAdminControllerClient() (admin.TChanControllerHostAdmin, error)
		GetThriftStoreClient(replica string, pathUUID string) (store.TChanBStore, error)
		ReleaseThriftStoreClient(pathUUID string)
		GetThriftStoreClientUUID(storeUUID string, contextID string) (store.TChanBStore, string, error)
		GetControllerClient() (controller.TChanController, error)
		GetReplicatorClient() (replicator.TChanReplicator, error)
	}
	adminControlClient struct {
		lk sync.Mutex  
		currentHostAddr string
		currentClient map[string]admin.TChanControllerHostAdmin
	}
	controllerClientCache struct {
		lk sync.RWMutex
		currentHostAddr string
		currentClient controller.TChanController
	}
	replicatorClientCache struct {
		lk sync.RWMutex
		currentHostAddr string
		currentClient replicator.TChanReplicator
	}
	chInfo struct {
		ref            int
		ch             *tchannel.Channel  
		currentClients map[string]store.TChanBStore
	}
	storeClient struct {
		lk sync.Mutex  
		currentCh map[string]*chInfo
	}
	thriftClientImpl struct {
		rpm              RingpopMonitor
		ch               *tchannel.Channel
		adminCClient     adminControlClient
		storeClients     storeClient
		cClient          controllerClientCache
		replicatorClient replicatorClientCache
		logger           bark.Logger
	}
)
var ErrNoClient = &cherami.InternalServiceError{Message: "Unable to create client"}
func NewClientFactory(rpm RingpopMonitor, ch *tchannel.Channel, log bark.Logger) ClientFactory {
	tClients := &thriftClientImpl{
		rpm: rpm,
		ch:  ch,
		adminCClient: adminControlClient{
			currentClient: make(map[string]admin.TChanControllerHostAdmin),
		},
		storeClients: storeClient{
			currentCh: make(map[string]*chInfo),
		},
		cClient: controllerClientCache{},
		logger:  log,
	}
	return tClients
}
func (h *thriftClientImpl) GetAdminControllerClient() (admin.TChanControllerHostAdmin, error) {
	var adminClient admin.TChanControllerHostAdmin
	var ok bool
	hostInfo, err := h.rpm.FindHostForKey(ControllerServiceName, ControllerServiceName)
	if err != nil {
		h.logger.WithFields(bark.Fields{TagErr: err}).Error("getControllerClient - Failed to find controller host")
		return nil, err
	}
	h.adminCClient.lk.Lock()
	if adminClient, ok = h.adminCClient.currentClient[hostInfo.Addr]; !ok {
		if _, exists := h.adminCClient.currentClient[h.adminCClient.currentHostAddr]; exists {
			h.logger.WithField(TagHostPort, FmtHostPort(h.adminCClient.currentHostAddr)).
				Debug("thriftClients: removing existing admin client from the map")
			delete(h.adminCClient.currentClient, h.adminCClient.currentHostAddr)
		}
		h.logger.WithField(TagHostPort, FmtHostPort(hostInfo.Addr)).
			Debug("thriftClients: creating new adminControlClient")
		extClient := thrift.NewClient(h.ch, ControllerServiceName, &thrift.ClientOptions{
			HostPort: hostInfo.Addr,
		})
		adminClient = admin.NewTChanControllerHostAdminClient(extClient)
		h.adminCClient.currentClient[hostInfo.Addr] = adminClient
		h.adminCClient.currentHostAddr = hostInfo.Addr
	}
	h.adminCClient.lk.Unlock()
	return adminClient, nil
}