func (h *Frontend) Start(thriftService []thrift.TChanServer) {
	h.SCommon.Start(thriftService)
	h.hostIDHeartbeater = common.NewHostIDHeartbeater(h.metaClnt, h.GetHostUUID(), h.GetHostPort(), h.GetHostName(), h.logger)
	h.hostIDHeartbeater.Start()
}
Start starts the frontend service and advertises in hyperbahn
package frontendhost
import (
	"context"
	"crypto/sha1"
	"encoding/base64"
	"fmt"
	"math"
	"net"
	"reflect"
	"regexp"
	"strconv"
	"strings"
	"sync"
	"time"
	ccli "github.com/uber/cherami-client-go/client/cherami"
	"github.com/uber/cherami-server/common"
	"github.com/uber/cherami-server/common/configure"
	dconfig "github.com/uber/cherami-server/common/dconfigclient"
	mm "github.com/uber/cherami-server/common/metadata"
	"github.com/uber/cherami-server/common/metrics"
	c "github.com/uber/cherami-thrift/.generated/go/cherami"
	"github.com/uber/cherami-thrift/.generated/go/controller"
	m "github.com/uber/cherami-thrift/.generated/go/metadata"
	"github.com/uber/cherami-thrift/.generated/go/shared"
	"github.com/uber-common/bark"
	"github.com/uber/tchannel-go/hyperbahn"
	"github.com/uber/tchannel-go/thrift"
)
const (
	maxSizeCacheDestinationPathForUUID = 1000
)
type ContextKey string
var ResourceUrnKey = ContextKey("resourceUrn")
var HeaderKey = ContextKey("header")
var nilRequestError = &c.BadRequestError{Message: `request must not be nil`}
var badRequestKafkaConfigError = &c.BadRequestError{Message: `kafka destination must set kafka cluster and topic, and may not be multi-zone`}
var badRequestNonKafkaConfigError = &c.BadRequestError{Message: `non-Kafka destination must not set kafka cluster and topic`}
var badRequestRecvOnlyPublishError = &c.BadRequestError{Message: `Cannot publish to RECEIVEONLY destinations`}
var badRequestKafkaPublishError = &c.BadRequestError{Message: `Cannot publish to Kafka destinations`}
type destinationUUID string
type Frontend struct {
	metaClnt          m.TChanMetadataService
	hostIDHeartbeater common.HostIDHeartbeater
	common.SCommon
	AppConfig                   configure.CommonAppConfig
	hyperbahnClient             *hyperbahn.Client
	cacheDestinationPathForUUID map[destinationUUID]string  
	lk                          sync.RWMutex
	logger                      bark.Logger
	cacheMutex                  sync.RWMutex
	cClient                     ccli.Client
	publishers                  map[string]*publisherInstance
	consumers                   map[string]*consumerInstance
	outputClientByUUID          map[string]c.TChanBOut
	m3Client                    metrics.Client
	dClient                     dconfig.Client
}
type publisherInstance struct {
	ccli.Publisher
	refCount int32
	idleTS time.Time
	receiptsChan chan *ccli.PublisherReceipt
}
type consumerInstance struct {
	ccli.Consumer
	refCount int32
	idleTS time.Time
	deliveryChan chan ccli.Delivery
}
var _ c.TChanBFrontend = &Frontend{}
func (h *Frontend) Shutdown() {
	h.logger.Info("Shutdown()")
	if h.hyperbahnClient != nil {
		h.hyperbahnClient.Close()
	}
}
func (h *Frontend) Stop() {
	h.hostIDHeartbeater.Stop()
	h.SCommon.Stop()
}
func NewFrontendHost(serviceName string, sVice common.SCommon, metadataClient m.TChanMetadataService, config configure.CommonAppConfig) (*Frontend, []thrift.TChanServer) {
	deploymentName := sVice.GetConfig().GetDeploymentName()
	bs := Frontend{
		logger:                      (sVice.GetConfig().GetLogger()).WithFields(bark.Fields{common.TagFrnt: common.FmtFrnt(sVice.GetHostUUID()), common.TagDplName: common.FmtDplName(deploymentName)}),
		SCommon:                     sVice,
		cacheDestinationPathForUUID: make(map[destinationUUID]string),
		cClient:                     nil,
		publishers:                  make(map[string]*publisherInstance),
		consumers:                   make(map[string]*consumerInstance),
		outputClientByUUID:          make(map[string]c.TChanBOut),
		AppConfig:                   config,
	}
	bs.logger.WithFields(bark.Fields{`serviceName`: serviceName}).Info(`New Frontend`)
	bs.m3Client = metrics.NewClient(sVice.GetMetricsReporter(), metrics.Frontend)
	bs.metaClnt = mm.NewMetadataMetricsMgr(metadataClient, bs.m3Client, bs.logger)
	bs.dClient = sVice.GetDConfigClient()
	bs.dynamicConfigManage()
	return &bs, []thrift.TChanServer{c.NewTChanBFrontendServer(&bs)}
}