• Raft详解-启动后运行期间代码


    Raft启动后运行期间主要执行两个函数;
    1、状态监测和转化

    func (rf *Raft) Loop() {
    // Set out as a follower

    TimeOutConst := 0
    for {
    TimeOutConst = ElectionTimeoutConst()
    if rf.state == "follower" {
    // DO FOLLOWER STUFF
    select {
    case <-rf.heartbeatCH:
    case <-time.After(time.Duration(TimeOutConst) * time.Millisecond):
    if rf.state != "leader" {
    rf.mu.Lock()
    // println(strconv.Itoa(rf.me) + " panic, term: " + strconv.Itoa(rf.CurrentTerm) + " len(rf.Logs): " + strconv.Itoa(len(rf.Logs)) + " voteCount: " + strconv.Itoa(rf.voteCount))
    rf.state = "candidate"
    rf.mu.Unlock()
    }
    }
    } else if rf.state == "candidate" {
    // DO CANDIDIATE STUFF
    rf.CandidateState()
    } else {
    // DO LEADER STUFF
    rf.LeaderState()
    }
    }
    }

    2、如果自己是一个leader,把client传过来的command编程log commit到各个server(通过RequestAppendEntries)和自己之后,向客户端返回结果表示 当前command已经被整个集群正式序列化

    func (rf *Raft) FeedStateMachine(applyCh chan ApplyMsg) {
    for {
    if rf.state == "leader" {
    rf.UpdateCommit()
    }
    time.Sleep(30 * time.Millisecond)
    if rf.LastApplied < rf.CommitIndex {
    go func() {
    rf.mu.Lock()
    oldApplied := rf.LastApplied
    commitIdx := rf.CommitIndex
    rf.LastApplied = commitIdx
    rf.mu.Unlock()
    if len(rf.Logs)-1 < commitIdx {
    return
    }
    time.Sleep(10 * time.Millisecond)
    for i := oldApplied+1; i <= commitIdx; i++ {
    Msg := new(ApplyMsg)
    Msg.Index = i
    Msg.Command = rf.Logs[i].Command
    applyCh <- *Msg
    }
    }()
    }
    }
    }

  • 相关阅读:
    c#冒泡排序算法和快速排序算法
    sqlserver 索引
    varchar和Nvarchar区别
    trigger
    sql语句
    超实用压力测试工具-ab工具
    js 页面离开前触发事件
    C# websocket与html js实现文件发送与接收处理
    C# socket编程 使用fleck轻松实现对话 https://github.com/statianzo/Fleck
    C# socket编程 使用udp实现单对单的连接对话
  • 原文地址:https://www.cnblogs.com/yanchengwang/p/5913815.html
Copyright © 2020-2023  润新知