Repository: matrixorigin/matrixcube
Pull request #681 (2022-02-22 03:44:04)

Amend prophet startup logic in order to improve readability;
**What type of PR is this?**

- [ ] API-change
- [ ] BUG
- [x] Improvement
- [ ] Documentation
- [ ] Feature
- [ ] Test and CI
- [ ] Code Refactoring

**Which issue(s) this PR fixes:**

Fixes #

**What this PR does / why we need it:**

Not Available

**Special notes for your reviewer:**

Not Available

**Additional documentation (e.g. design docs, usage docs, etc.):**

Not Available


cnutshell: Aim to readability improvement:
- Change configuration field `storage-node` to `prophet-node`;
- Amend name for some variables and functions;
- Amend code structure and format;

Patch:
diff --git a/components/prophet/cluster/cluster.go b/components/prophet/cluster/cluster.go
index 22ae7ca..6b892a6 100644
--- a/components/prophet/cluster/cluster.go
+++ b/components/prophet/cluster/cluster.go
@@ -93,16 +93,16 @@ type RaftCluster struct {
 	storage storage.Storage
 	limiter *StoreLimiter
 
-	prepareChecker  *prepareChecker
-	changedEvents   chan rpcpb.EventNotify
-	createShardC chan struct{}
+	prepareChecker *prepareChecker
+	changedEvents  chan rpcpb.EventNotify
+	createShardC   chan struct{}
 
 	labelLevelStats *statistics.LabelStatistics
 	resourceStats   *statistics.ShardStatistics
 	hotStat         *statistics.HotStat
 
 	coordinator      *coordinator
-	suspectShards *cache.TTLUint64 // suspectShards are resources that may need fix
+	suspectShards    *cache.TTLUint64 // suspectShards are resources that may need fix
 	suspectKeyRanges *cache.TTLString // suspect key-range resources that may need fix
 
 	wg   sync.WaitGroup
@@ -117,13 +117,15 @@ type RaftCluster struct {
 }
 
 // NewRaftCluster create a new cluster.
-func NewRaftCluster(ctx context.Context,
+func NewRaftCluster(
+	ctx context.Context,
 	root string,
 	clusterID uint64,
 	etcdClient *clientv3.Client,
 	adapter metadata.Adapter,
 	resourceStateChangedHandler func(res metadata.Shard, from metapb.ShardState, to metapb.ShardState),
-	logger *zap.Logger) *RaftCluster {
+	logger *zap.Logger,
+) *RaftCluster {
 	return &RaftCluster{
 		ctx:                         ctx,
 		running:                     false,
@@ -1364,14 +1366,14 @@ func (c *RaftCluster) FitShard(res *core.CachedShard) *placement.ShardFit {
 
 type prepareChecker struct {
 	reactiveShards map[uint64]int
-	start             time.Time
-	sum               int
-	isPrepared        bool
+	start          time.Time
+	sum            int
+	isPrepared     bool
 }
 
 func newPrepareChecker() *prepareChecker {
 	return &prepareChecker{
-		start:             time.Now(),
+		start:          time.Now(),
 		reactiveShards: make(map[uint64]int),
 	}
 }
diff --git a/components/prophet/config/config.go b/components/prophet/config/config.go
index 009b024..b56d590 100644
--- a/components/prophet/config/config.go
+++ b/components/prophet/config/config.go
@@ -40,7 +40,7 @@ type Config struct {
 	RPCTimeout       typeutil.Duration `toml:"rpc-timeout"`
 
 	// etcd configuration
-	StorageNode  bool            `toml:"storage-node"`
+	ProphetNode  bool            `toml:"prophet-node"`
 	ExternalEtcd []string        `toml:"external-etcd"`
 	EmbedEtcd    EmbedEtcdConfig `toml:"embed-etcd"`
 
diff --git a/components/prophet/config/default.go b/components/prophet/config/default.go
index e515732..53d2bcf 100644
--- a/components/prophet/config/default.go
+++ b/components/prophet/config/default.go
@@ -113,7 +113,7 @@ func (c *Config) Adjust(meta *toml.MetaData, reloading bool) error {
 		return err
 	}
 
-	if c.StorageNode {
+	if c.ProphetNode {
 		adjustString(&c.EmbedEtcd.ClientUrls, defaultClientUrls)
 		adjustString(&c.EmbedEtcd.AdvertiseClientUrls, c.EmbedEtcd.ClientUrls)
 		adjustString(&c.EmbedEtcd.PeerUrls, defaultPeerUrls)
diff --git a/components/prophet/election/election.go b/components/prophet/election/election.go
index e53e739..0758d82 100644
--- a/components/prophet/election/election.go
+++ b/components/prophet/election/election.go
@@ -29,7 +29,7 @@ var (
 // Elector a leader elector
 type Elector interface {
 	// CreateLeadship create a leadership
-	CreateLeadship(purpose string, nodeName, nodeValue string, allowCampaign bool, becomeLeader, becomeFollower func(string) bool) *Leadership
+	CreateLeadship(purpose string, nodeName, nodeValue string, allowBecomeLeader bool, becomeLeaderFunc, becomeFollowerFunc func(string) bool) *Leadership
 	// Client etcd clientv3
 	Client() *clientv3.Client
 }
@@ -38,14 +38,14 @@ type elector struct {
 	sync.RWMutex
 	options electorOptions
 	client  *clientv3.Client
-	lessor  clientv3.Lease
+	lease   clientv3.Lease
 }
 
 // NewElector create a elector
 func NewElector(client *clientv3.Client, options ...ElectorOption) (Elector, error) {
 	e := &elector{
 		client: client,
-		lessor: clientv3.NewLease(client),
+		lease:  clientv3.NewLease(client),
 	}
 
 	for _, opt := range options {
@@ -57,8 +57,8 @@ func NewElector(client *clientv3.Client, options ...ElectorOption) (Elector, err
 	return e, nil
 }
 
-func (e *elector) CreateLeadship(purpose string, nodeName, nodeValue string, allowCampaign bool, becomeLeader, becomeFollower func(string) bool) *Leadership {
-	return newLeadership(e, purpose, nodeName, nodeValue, allowCampaign, becomeLeader, becomeFollower, e.options.logger)
+func (e *elector) CreateLeadship(purpose string, nodeName, nodeValue string, allowBecomeLeader bool, becomeLeaderFunc, becomeFollowerFunc func(string) bool) *Leadership {
+	return newLeadership(e, purpose, nodeName, nodeValue, allowBecomeLeader, becomeLeaderFunc, becomeFollowerFunc, e.options.logger)
 }
 
 func (e *elector) Client() *clientv3.Client {
diff --git a/components/prophet/election/election_leadship.go b/components/prophet/election/election_leadship.go
index 0ff7be4..3cd63e4 100644
--- a/components/prophet/election/election_leadship.go
+++ b/components/prophet/election/election_leadship.go
@@ -50,32 +50,33 @@ type Leadership struct {
 	nodeName  string
 	nodeValue string
 
-	ctx                          context.Context
-	allowCampaign                bool
-	becomeLeader, becomeFollower func(string) bool
-	stopper                      *stop.Stopper
-	logger                       *zap.Logger
+	ctx                                  context.Context
+	allowBecomeLeader                    bool
+	becomeLeaderFunc, becomeFollowerFunc func(string) bool
+	stopper                              *stop.Stopper
+	logger                               *zap.Logger
 }
 
-func newLeadership(elector *elector,
+func newLeadership(
+	elector *elector,
 	purpose, nodeName, nodeValue string,
-	allowCampaign bool,
-	becomeLeader, becomeFollower func(string) bool,
-	logger *zap.Logger) *Leadership {
+	allowBecomeLeader bool,
+	becomeLeaderFunc, becomeFollowerFunc func(string) bool,
+	logger *zap.Logger,
+) *Leadership {
 	tag := fmt.Sprintf("[%s/%s]", purpose, nodeName)
 	return &Leadership{
-		purpose:        purpose,
-		elector:        elector,
-		leaderKey:      getPurposePath(elector.options.leaderPath, purpose),
-		nodeValue:      nodeValue,
-		nodeName:       nodeName,
-		allowCampaign:  allowCampaign,
-		becomeLeader:   becomeLeader,
-		becomeFollower: becomeFollower,
-		tag:            tag,
-		logger: log.Adjust(logger).With(zap.String("tag", tag),
-			zap.String("purpose", purpose)),
-		stopper: stop.NewStopper("leadership"),
+		purpose:            purpose,
+		elector:            elector,
+		leaderKey:          getPurposePath(elector.options.leaderPath, purpose),
+		nodeValue:          nodeValue,
+		nodeName:           nodeName,
+		allowBecomeLeader:  allowBecomeLeader,
+		becomeLeaderFunc:   becomeLeaderFunc,
+		becomeFollowerFunc: becomeFollowerFunc,
+		tag:                tag,
+		logger:             log.Adjust(logger).With(zap.String("tag", tag), zap.String("purpose", purpose)),
+		stopper:            stop.NewStopper("leadership"),
 	}
 }
 
@@ -164,80 +165,81 @@ func (ls *Leadership) ElectionLoop() {
 func (ls *Leadership) doElectionLoop(ctx context.Context) {
 	ls.ctx = ctx
 	for {
-		ls.logger.Info("ready to next loop",
-			mainLoopFiled)
+		ls.logger.Info("ready to next loop", mainLoopFiled)
+
 		select {
 		case <-ctx.Done():
-			ls.logger.Info("loop exit due to context done",
-				mainLoopFiled)
+			ls.logger.Info("loop exit due to context done", mainLoopFiled)
 			return
 		default:
-			ls.logger.Info("ready to load current leader",
-				mainLoopFiled)
-			currentLeader, rev, err := ls.CurrentLeader()
-			if err != nil {
-				ls.logger.Error("fail to load current leader, retry later",
-					mainLoopFiled,
-					zap.Error(err))
-				time.Sleep(loopInterval)
-				continue
-			}
-			ls.logger.Info("current leader loaded",
+		}
+
+		ls.logger.Info("ready to load current leader", mainLoopFiled)
+		currentLeader, rev, err := ls.CurrentLeader()
+		if err != nil {
+			ls.logger.Error("fail to load current leader, retry later",
 				mainLoopFiled,
-				zap.String("leader", currentLeader))
-
-			if len(currentLeader) > 0 {
-				if ls.nodeValue != "" && currentLeader == ls.nodeValue {
-					// oh, we are already leader, we may meet something wrong
-					// in previous campaignLeader. we can resign and campaign again.
-					ls.logger.Warn("matched, resign and campaign again")
-					if err = ls.resign(); err != nil {
-						ls.logger.Warn("fail to resign leader",
-							mainLoopFiled,
-							zap.Error(err))
-						time.Sleep(loopInterval)
-						continue
-					}
-				} else {
-					ls.logger.Info("start watch leader",
-						mainLoopFiled,
-						zap.String("leader", currentLeader))
-					ls.becomeFollower(currentLeader)
-					ls.watch(rev)
-					ls.becomeFollower("")
-					ls.logger.Info("leader out",
-						mainLoopFiled,
-						zap.String("leader", currentLeader))
-				}
-			}
+				zap.Error(err),
+			)
+			time.Sleep(loopInterval)
+			continue
+		}
 
-			if ls.allowCampaign {
-				ls.logger.Info("start checkExpectLeader",
-					mainLoopFiled)
-				// check expect leader exists
-				err := ls.checkExpectLeader()
-				if err != nil {
-					ls.logger.Error("fail to check expect leader",
-						mainLoopFiled,
-						zap.Error(err))
-					time.Sleep(200 * time.Millisecond)
-					continue
-				}
-				ls.logger.Info("end checkExpectLeader, and start campaign",
-					mainLoopFiled)
-				if err = ls.campaign(); err != nil {
-					ls.logger.Error("fail to campaign leader",
-						mainLoopFiled,
-						zap.Error(err))
-					time.Sleep(time.Second * time.Duration(ls.elector.options.leaseSec))
+		ls.logger.Info("current leader loaded", mainLoopFiled,
+			zap.String("leader", currentLeader),
+		)
+
+		if len(currentLeader) > 0 {
+			if ls.nodeValue != "" && currentLeader == ls.nodeValue {
+				// oh, we are already leader, we may meet something wrong
+				// in previous campaignLeader. we can resign and campaign again.
+				ls.logger.Warn("matched, resign and campaign again")
+
+				if err := ls.resign(); err != nil {
+					ls.logger.Warn("fail to resign leader", mainLoopFiled,
+						zap.Error(err),
+					)
+					time.Sleep(loopInterval)
 					continue
 				}
-				ls.logger.Info("end campaign",
-					mainLoopFiled)
+			} else {
+				ls.logger.Info("start to watch current leader", mainLoopFiled,
+					zap.String("leader", currentLeader),
+				)
+
+				ls.becomeFollowerFunc(currentLeader)
+				ls.watch(rev)
+				ls.becomeFollowerFunc("")
+
+				ls.logger.Info("current leader out", mainLoopFiled,
+					zap.String("leader", currentLeader),
+				)
 			}
+		}
 
-			time.Sleep(loopInterval)
+		if ls.allowBecomeLeader {
+			ls.logger.Info("start checkExpectLeader", mainLoopFiled)
+			if err := ls.checkExpectLeader(); err != nil {
+				ls.logger.Error("fail to check expect leader", mainLoopFiled,
+					zap.Error(err),
+				)
+				time.Sleep(200 * time.Millisecond)
+				continue
+			}
+
+			ls.logger.Info("end checkExpectLeader, and start campaign", mainLoopFiled)
+			if err := ls.campaign(); err != nil {
+				ls.logger.Error("fail to campaign leader", mainLoopFiled,
+					zap.Error(err),
+				)
+				time.Sleep(time.Second * time.Duration(ls.elector.options.leaseSec))
+				continue
+			}
+
+			ls.logger.Info("end campaign", mainLoopFiled)
 		}
+
+		time.Sleep(loopInterval)
 	}
 }
 
@@ -313,14 +315,14 @@ func (ls *Leadership) campaign() error {
 			keepaliveField)
 	}
 
-	if !ls.becomeLeader(ls.nodeValue) {
+	if !ls.becomeLeaderFunc(ls.nodeValue) {
 		ls.logger.Info("become leader func return false",
 			keepaliveField)
 		return nil
 	}
 
 	defer func() {
-		ls.becomeFollower("")
+		ls.becomeFollowerFunc("")
 		if lock != nil {
 			lock.Unlock(ls.ctx)
 			ls.logger.Info("lock released",
@@ -458,7 +460,7 @@ func (ls *Leadership) checkExpectLeader() error {
 
 func (ls *Leadership) addExpectLeader(newLeader string) error {
 	ctx, cancel := context.WithTimeout(ls.elector.client.Ctx(), option.DefaultRequestTimeout)
-	leaseResp, err := ls.elector.lessor.Grant(ctx, ls.elector.options.leaseSec)
+	leaseResp, err := ls.elector.lease.Grant(ctx, ls.elector.options.leaseSec)
 	cancel()
 
 	if err != nil {
diff --git a/components/prophet/member/member.go b/components/prophet/member/member.go
index 6e08392..b537bbf 100644
--- a/components/prophet/member/member.go
+++ b/components/prophet/member/member.go
@@ -27,7 +27,7 @@ import (
 
 // Member is used for the election related logic.
 type Member struct {
-	candidate                            bool
+	isProphet                            bool
 	etcd                                 *embed.Etcd
 	client                               *clientv3.Client
 	elector                              election.Elector
@@ -41,12 +41,14 @@ type Member struct {
 }
 
 // NewMember create a new Member.
-func NewMember(client *clientv3.Client,
+func NewMember(
+	client *clientv3.Client,
 	etcd *embed.Etcd,
 	elector election.Elector,
-	candidate bool,
+	isProphet bool,
 	becomeLeaderFunc, becomeFollowerFunc func() error,
-	logger *zap.Logger) *Member {
+	logger *zap.Logger,
+) *Member {
 	id := uint64(0)
 	if etcd != nil {
 		id = uint64(etcd.Server.ID())
@@ -55,7 +57,7 @@ func NewMember(client *clientv3.Client,
 	return &Member{
 		client:             client,
 		elector:            elector,
-		candidate:          candidate,
+		isProphet:          isProphet,
 		becomeLeaderFunc:   becomeLeaderFunc,
 		becomeFollowerFunc: becomeFollowerFunc,
 		etcd:               etcd,
@@ -86,7 +88,7 @@ func (m *Member) Stop() {
 	}
 }
 
-func (m *Member) disableLeader(newLeader string) bool {
+func (m *Member) becomeFollower(newLeader string) bool {
 	if newLeader == "" {
 		m.leader.Store(&metapb.Member{})
 		if err := m.becomeFollowerFunc(); err != nil {
@@ -108,7 +110,7 @@ func (m *Member) disableLeader(newLeader string) bool {
 	return true
 }
 
-func (m *Member) enableLeader(newLeader string) bool {
+func (m *Member) becomeLeader(newLeader string) bool {
 	m.leader.Store(m.member)
 	if err := m.becomeLeaderFunc(); err != nil {
 		return false
@@ -141,22 +143,25 @@ func (m *Member) ElectionLoop() {
 }
 
 // MemberInfo initializes the member info.
-func (m *Member) MemberInfo(name, addr string) {
-	leader := &metapb.Member{
+func (m *Member) MemberInfo(nodeName, addr string) {
+	member := &metapb.Member{
 		ID:   m.id,
-		Name: name,
+		Name: nodeName,
 		Addr: addr,
 	}
 
-	data, err := leader.Marshal()
+	data, err := member.Marshal()
 	if err != nil {
 		// can't fail, so panic here.
-		m.logger.Fatal("fail to marshal prophet leader",
-			zap.Error(err))
+		m.logger.Fatal("fail to marshal prophet member info", zap.Error(err))
 	}
-	m.member = leader
+
+	m.member = member
 	m.memberValue = string(data)
-	m.leadership = m.elector.CreateLeadship("prophet-leader", name, m.memberValue, m.candidate, m.enableLeader, m.disableLeader)
+	m.leadership = m.elector.CreateLeadship(
+		"prophet-leader", nodeName, m.memberValue,
+		m.isProphet, m.becomeLeader, m.becomeFollower,
+	)
 }
 
 // IsLeader returns whether the server is prophet leader or not by checking its leadership's lease and leader info.
diff --git a/components/prophet/prophet.go b/components/prophet/prophet.go
index c4112fe..f6441d2 100644
--- a/components/prophet/prophet.go
+++ b/components/prophet/prophet.go
@@ -119,12 +119,14 @@ func NewProphet(cfg *config.Config) Prophet {
 	var err error
 	ctx, cancel := context.WithCancel(context.Background())
 
-	if cfg.Prophet.StorageNode {
+	if cfg.Prophet.ProphetNode {
+		// start embedded-etcd for prophet node
 		etcdClient, etcd, err = join.PrepareJoinCluster(ctx, cfg, logger)
 		if err != nil {
 			logger.Fatal("fail to start embed etcd", zap.Error(err))
 		}
 	} else {
+		// non-prophet node would watch current prophet leader via etcd client
 		etcdClient, err = clientv3.New(clientv3.Config{
 			Endpoints:        cfg.Prophet.ExternalEtcd,
 			AutoSyncInterval: time.Second * 30,
@@ -132,36 +134,45 @@ func NewProphet(cfg *config.Config) Prophet {
 			Logger:           logger,
 		})
 		if err != nil {
-			logger.Fatal("fail to create external etcd client",
-				zap.Error(err))
+			logger.Fatal("fail to create external etcd client", zap.Error(err))
 		}
 	}
 
-	elector, err = election.NewElector(etcdClient,
+	// elector is mainly a wrapper of etcd client
+	elector, err = election.NewElector(
+		etcdClient,
 		election.WithLeaderLeaseSeconds(cfg.Prophet.LeaderLease),
 		election.WithEmbedEtcd(etcd),
-		election.WithLogger(log.Adjust(cfg.Logger).Named("elector")))
+		election.WithLogger(logger.Named("elector")),
+	)
 	if err != nil {
 		logger.Fatal("fail to create elector", zap.Error(err))
 	}
 
-	p := &defaultProphet{}
-	p.logger = logger
-	p.cfg = cfg
-	p.persistOptions = pconfig.NewPersistOptions(&cfg.Prophet, logger)
-	p.ctx = ctx
-	p.cancel = cancel
-	p.elector = elector
-	p.etcd = etcd
-	p.member = member.NewMember(etcdClient, etcd, elector, cfg.Prophet.StorageNode, p.enableLeader, p.disableLeader, logger)
-	p.completeC = make(chan struct{})
+	p := &defaultProphet{
+		logger:         logger,
+		ctx:            ctx,
+		cancel:         cancel,
+		cfg:            cfg,
+		persistOptions: pconfig.NewPersistOptions(&cfg.Prophet, logger),
+		etcd:           etcd,
+		elector:        elector,
+		completeC:      make(chan struct{}),
+		stopper:        stop.NewStopper("prophet", stop.WithLogger(logger)),
+	}
+
+	p.member = member.NewMember(
+		etcdClient, etcd, elector,
+		cfg.Prophet.ProphetNode, p.becomeLeader, p.becomeFollower, logger,
+	)
 	p.jobMu.jobs = make(map[metapb.JobType]metapb.Job)
-	p.stopper = stop.NewStopper("prophet", stop.WithLogger(p.logger))
+
 	return p
 }
 
 func (p *defaultProphet) Start() {
 	p.logger.Info("begin to start prophet")
+
 	var err error
 	for i := 0; i < initClusterMaxRetryTimes; i++ {
 		if err = p.initClusterID(); err == nil {
@@ -169,24 +180,28 @@ func (p *defaultProphet) Start() {
 		}
 	}
 	if err != nil {
-		p.logger.Fatal("fail to init cluster",
-			zap.Error(err))
+		p.logger.Fatal("fail to init cluster", zap.Error(err))
 	}
 	p.logger.Info("init cluster id completed")
 
 	p.member.MemberInfo(p.cfg.Prophet.Name, p.cfg.Prophet.AdvertiseRPCAddr)
 	p.logger.Info("member init completed")
 
-	p.storage = storage.NewStorage(rootPath,
+	p.storage = storage.NewStorage(
+		rootPath,
 		storage.NewEtcdKV(rootPath, p.elector.Client(), p.member.GetLeadership()),
-		p.cfg.Prophet.Adapter)
+		p.cfg.Prophet.Adapter,
+	)
 	p.logger.Info("storage created")
 
 	p.basicCluster = core.NewBasicCluster(p.cfg.Prophet.Adapter.NewShard, p.logger)
 	p.logger.Info("basic cluster created")
 
-	p.cluster = cluster.NewRaftCluster(p.ctx, rootPath, p.clusterID, p.elector.Client(), p.cfg.Prophet.Adapter,
-		p.cfg.Prophet.ShardStateChangedHandler, p.logger)
+	p.cluster = cluster.NewRaftCluster(
+		p.ctx, rootPath, p.clusterID, p.elector.Client(),
+		p.cfg.Prophet.Adapter,
+		p.cfg.Prophet.ShardStateChangedHandler, p.logger,
+	)
 	p.logger.Info("raft cluster created")
 
 	p.hbStreams = hbstream.NewHeartbeatStreams(p.ctx, p.clusterID, p.cluster, p.logger)
@@ -197,7 +212,7 @@ func (p *defaultProphet) Start() {
 	p.startListen()
 	p.logger.Info("rpc started")
 
-	p.startLeaderLoop()
+	p.startElectionLoop()
 	p.logger.Info("lead loop completed")
 }
 
@@ -209,7 +224,7 @@ func (p *defaultProphet) Stop() {
 		p.logger.Info("client stopped")
 
 		p.trans.Stop()
-		p.logger.Info("transport stopped")
+		p.logger.Info("RPC stopped")
 
 		p.cancel()
 		p.elector.Client().Close()
@@ -251,6 +266,7 @@ func (p *defaultProphet) GetClusterID() uint64 {
 	return p.clusterID
 }
 
+// initClusterID initialize prophet cluster ID
 func (p *defaultProphet) initClusterID() error {
 	// Get any cluster key to parse the cluster ID.
 	resp, err := util.GetEtcdResp(p.elector.Client(), clusterIDPath)
@@ -331,8 +347,11 @@ func (p *defaultProphet) GetBasicCluster() *core.BasicCluster {
 	return p.basicCluster
 }
 
+// startSystemMonitor start a goroutine in order to monitor system time
 func (p *defaultProphet) startSystemMonitor() {
-	go StartMonitor(p.ctx, time.Now, func() {
-		p.logger.Error("system time jumps backward")
-	}, p.logger)
+	systimeErrHandler := func() { p.logger.Error("system time jumps backward") }
+	task := func(ctx context.Context) {
+		StartMonitor(ctx, time.Now, systimeErrHandler, p.logger)
+	}
+	p.stopper.RunNamedTask(p.ctx, "system time monitor", task)
 }
diff --git a/components/prophet/prophet_handler.go b/components/prophet/prophet_handler.go
old mode 100755
new mode 100644
diff --git a/components/prophet/prophet_leader.go b/components/prophet/prophet_leader.go
index 93f5aad..2817aa6 100644
--- a/components/prophet/prophet_leader.go
+++ b/components/prophet/prophet_leader.go
@@ -17,13 +17,14 @@ import (
 	"go.uber.org/zap"
 )
 
-func (p *defaultProphet) startLeaderLoop() {
+// startLeaderLoop start election loop
+func (p *defaultProphet) startElectionLoop() {
 	p.member.ElectionLoop()
-	p.logger.Info("lead loop started")
+	p.logger.Info("election loop started")
 	<-p.completeC
 }
 
-func (p *defaultProphet) enableLeader() error {
+func (p *defaultProphet) becomeLeader() error {
 	p.logger.Info("********become leader now********")
 
 	if err := p.createRaftCluster(); err != nil {
@@ -40,7 +41,7 @@ func (p *defaultProphet) enableLeader() error {
 	return nil
 }
 
-func (p *defaultProphet) disableLeader() error {
+func (p *defaultProphet) becomeFollower() error {
 	p.logger.Info("********become follower now********")
 
 	p.initClient()
diff --git a/components/prophet/prophet_transport.go b/components/prophet/prophet_transport.go
index f5b8d07..1a4eb8e 100644
--- a/components/prophet/prophet_transport.go
+++ b/components/prophet/prophet_transport.go
@@ -20,6 +20,7 @@ import (
 	"go.uber.org/zap"
 )
 
+// startListen launch RPC service
 func (p *defaultProphet) startListen() {
 	encoder, decoder := codec.NewServerCodec(10 * buf.MB)
 	app, err := goetty.NewTCPApplication(


Test patch:
diff --git a/components/prophet/prophet_test.go b/components/prophet/prophet_test.go
index 4da19d3..5f5a210 100644
--- a/components/prophet/prophet_test.go
+++ b/components/prophet/prophet_test.go
@@ -62,7 +62,7 @@ func TestClusterStart(t *testing.T) {
 
 func newTestSingleProphet(t *testing.T, adjustFunc func(*pconfig.Config)) Prophet {
 	c := pconfig.NewConfig()
-	c.StorageNode = true
+	c.ProphetNode = true
 	if adjustFunc != nil {
 		adjustFunc(c)
 	}
@@ -85,7 +85,7 @@ func newTestClusterProphet(t *testing.T, n int, adjustFunc func(*pconfig.Config)
 		c.DataDir = fmt.Sprintf("/tmp/prophet/%s", c.Name)
 		c.RPCAddr = fmt.Sprintf("127.0.0.1:1000%d", i)
 		if i < 3 {
-			c.StorageNode = true
+			c.ProphetNode = true
 			c.EmbedEtcd.ClientUrls = fmt.Sprintf("http://127.0.0.1:2000%d", i)
 			c.EmbedEtcd.PeerUrls = fmt.Sprintf("http://127.0.0.1:3000%d", i)
 			c.EmbedEtcd.TickInterval.Duration = time.Millisecond * 50
diff --git a/raftstore/testutil.go b/raftstore/testutil.go
index af2096f..275fd6b 100644
--- a/raftstore/testutil.go
+++ b/raftstore/testutil.go
@@ -1040,7 +1040,7 @@ func (c *testRaftCluster) resetNode(node int, init bool) {
 	cfg.Prophet.AdvertiseRPCAddr = fmt.Sprintf("%s:%d", advertiseIP, c.portsRPCAddr[node])
 	cfg.Prophet.Schedule.EnableJointConsensus = true
 	if node < 3 {
-		cfg.Prophet.StorageNode = true
+		cfg.Prophet.ProphetNode = true
 		if node != 0 {
 			cfg.Prophet.EmbedEtcd.Join = fmt.Sprintf("http://%s:%d", advertiseIP, c.portsEtcdClient[0])
 		}
@@ -1059,7 +1059,7 @@ func (c *testRaftCluster) resetNode(node int, init bool) {
 			cfg.Prophet.EmbedEtcd.InitialCluster = cfg.Prophet.EmbedEtcd.InitialCluster[:len(cfg.Prophet.EmbedEtcd.InitialCluster)-1]
 		}
 	} else {
-		cfg.Prophet.StorageNode = false
+		cfg.Prophet.ProphetNode = false
 		cfg.Prophet.ExternalEtcd = []string{
 			fmt.Sprintf("http://%s:%d", advertiseIP, c.portsEtcdClient[0]),
 			fmt.Sprintf("http://%s:%d", advertiseIP, c.portsEtcdClient[1]),