func (s *RaftServer) ReplicateLog(cmd *entity.Command) ([]byte, error) {
	prevLogIndex := getLastLogIndex(s)
	appendLogEntry(s, cmd)
	countlog.Info("ReplicateLog to follwers", "cmd", cmd)
	appendRPCMsg := make(chan replcateResult, len(s.ServerConf.ClusterAddrList)-1)
	for _, server := range s.ServerConf.ClusterAddrList {
		if server.ServerID == s.ServerConf.Info.ServerID {
			continue
		}
		s.wgHandleCommand.Add(1)
		go s.replicateLogToServer(server.ServerAddr, buildAppendRPCRequest(s, server, prevLogIndex), appendRPCMsg)
	}
	success := 1
	go func(appendRPCMsg chan replcateResult) {
		for res := range appendRPCMsg {
			if res.returnStatus == SUCCESS {
				if res.Success {
					s.leaderState.NextIndex[res.followerID] = s.stableInfo.Logs.GetNextIndex()
					s.leaderState.MatchIndex[res.followerID] = s.stableInfo.Logs.GetLastIndex()
					s.leaderState.LastRPCTime[res.followerID] = time.Now()
					success++
				}
			}
		}
	}(appendRPCMsg)
	s.wgHandleCommand.Wait()
	close(appendRPCMsg)

	if success*2 > len(s.ServerConf.ClusterAddrList) {
		// replicate success
		s.volatileInfo.CommitIndex = s.stableInfo.Logs.GetLastIndex()
		s.applyLogs()
		return s.dbStore.Get(cmd.Key)
	}
	return nil, errmsg.ReplicateLogFail
}
// ReplicateLog replicates logs to follower
ReplicateLog replicates logs to follower
// ReplicateLog replicates logs to follower
func (s *RaftServer) ReplicateLog(cmd *entity.Command) ([]byte, error) {
	prevLogIndex := getLastLogIndex(s)
	appendLogEntry(s, cmd)
	countlog.Info("ReplicateLog to follwers", "cmd", cmd)
	appendRPCMsg := make(chan replcateResult, len(s.ServerConf.ClusterAddrList)-1)
	for _, server := range s.ServerConf.ClusterAddrList {
		if server.ServerID == s.ServerConf.Info.ServerID {
			continue
		}
		s.wgHandleCommand.Add(1)
		go s.replicateLogToServer(server.ServerAddr, buildAppendRPCRequest(s, server, prevLogIndex), appendRPCMsg)
	}
	success := 1
	go func(appendRPCMsg chan replcateResult) {
		for res := range appendRPCMsg {
			if res.returnStatus == SUCCESS {
				if res.Success {
					s.leaderState.NextIndex[res.followerID] = s.stableInfo.Logs.GetNextIndex()
					s.leaderState.MatchIndex[res.followerID] = s.stableInfo.Logs.GetLastIndex()
					s.leaderState.LastRPCTime[res.followerID] = time.Now()
					success++
				}
			}
		}
	}(appendRPCMsg)
	s.wgHandleCommand.Wait()
	close(appendRPCMsg)
	if success*2 > len(s.ServerConf.ClusterAddrList) {
		s.volatileInfo.CommitIndex = s.stableInfo.Logs.GetLastIndex()
		s.applyLogs()
		return s.dbStore.Get(cmd.Key)
	}
	return nil, errmsg.ReplicateLogFail
}
func ( s * RaftServer ) ReplicateLog ( cmd * entity . Command ) ( [ ] byte , error ) { prevLogIndex := getLastLogIndex ( s ) appendLogEntry ( s , cmd ) countlog . Info ( " " , " " , cmd ) appendRPCMsg := make ( chan replcateResult , len ( s . ServerConf . ClusterAddrList ) - 1 ) for _ , server := range s . ServerConf . ClusterAddrList { if server . ServerID == s . ServerConf . Info . ServerID { continue } s . wgHandleCommand . Add ( 1 ) go s . replicateLogToServer ( server . ServerAddr , buildAppendRPCRequest ( s , server , prevLogIndex ) , appendRPCMsg ) } success := 1 go func ( appendRPCMsg chan replcateResult ) { for res := range appendRPCMsg { if res . returnStatus == SUCCESS { if res . Success { s . leaderState . NextIndex [ res . followerID ] = s . stableInfo . Logs . GetNextIndex ( ) s . leaderState . MatchIndex [ res . followerID ] = s . stableInfo . Logs . GetLastIndex ( ) s . leaderState . LastRPCTime [ res . followerID ] = time . Now ( ) success ++ } } } } ( appendRPCMsg ) s . wgHandleCommand . Wait ( ) close ( appendRPCMsg ) if success * 2 > len ( s . ServerConf . ClusterAddrList ) { s . volatileInfo . CommitIndex = s . stableInfo . Logs . GetLastIndex ( ) s . applyLogs ( ) return s . dbStore . Get ( cmd . Key ) } return nil , errmsg . ReplicateLogFail }
ReplicateLog replicates logs to follower
ReplicateLog replicates logs to follower
// replicate success