Ejemplo n.º 1
0
    def recvProposal(self, msg):
        if msg.cmd == Message.MSG_PROPOSE:  #处理提议
            self.proposalID = msg.proposalID  #协议编号
            self.instanceID = msg.instanceID  #记录编号
            (port, count) = self.client.getHighestProposal(msg.instanceID)  #获取端口,协议最高编号

            #[start---1.3] AcceptorProtocol收到一个提议,判断提议版本回复承诺接受消息或拒绝消息
            #判断协议是否是最高版本,版本相同时优先接收端口号高的提议消息
            if count < self.proposalID[0] \
                    or (count == self.proposalID[0] and port < self.proposalID[1]):
                self.state = PaxoAcceptorProtocol.STATE_PROPOSAL_AGREED  #Acceptor当前已经承诺给某Proposer会接受请求
                print("承诺会接受该提议:%s, %s " % (msg.instanceID, msg.value))
                value = self.client.getInstanceValue(msg.instanceID)  #抓取记录的数据值

                msg_agree = Message(Message.MSG_ACCEPTOR_AGREE)  #创建一个消息作为对Proposer的承诺
                msg_agree.copyAsReply(msg)  #拷贝并回复
                msg_agree.value = value  #保存值
                msg_agree.sequence = (port, count)  #保存端口数据
                self.client.sendMsg(msg_agree)  #给Proposer回复承诺消息

            else:
                #提议版本过低,我已经承诺给别的Proposer  所以拒绝
                self.state = PaxoAcceptorProtocol.STATE_PROPOSAL_REJECTED

            return self.proposalID

        else:
            pass
Ejemplo n.º 2
0
 def recvProposal(self, message):  #收取
     if message.command == Message.MSG_PROPOSE:  #处理协议
         self.proposalID = message.proposalID  #协议编号
         self.instanceID = message.instanceID
         (port,
          count) = self.client.getHighestAgreedProposal(message.instanceID)
         # 监测编号处理消息协议
         # 判断协议是不是最高的
         if count < self.proposalID[0] or (count == self.proposalID[0]
                                           and port < self.proposalID[1]):
             self.state = PaxosAcceptorProtocol.STATE_PROPOSAL_AGREED  #协议统一
             print("同意协议:%s, %s " % (message.instanceID, message.value))
             value = self.client.getInstanceValue(message.instanceID)  #抓取数据
             msg = Message(Message.MSG_ACCEPTOR_AGREE)  #同意协议
             msg.copyAsReply(message)  #拷贝并回复
             msg.value = value  #保存值
             msg.sequence = (port, count)  #保存数据
             self.client.sendMessage(msg)  #发送消息
         else:
             self.state = PaxosAcceptorProtocol.STATE_PROPOSAL_REJECTED
             # 拒绝状态
         return self.proposalID
     else:
         # 错误重新尝试
         pass
Ejemplo n.º 3
0
 def doTranition(self, message):  #过度
     if self.state==PaxosAccepterProtocol.STATE_PROPOSAL_AGREED and \
         message.command==Message.MSG_ACCEPT:
         self.state = PaxosAccepterProtocol.STATE_PROPOSAL_ACCEPTED  #接受协议
         msg = Message(Message.MSG_ACCEPTOR_ACCEPT)  #创建消息
         msg.copyAsReply(message)  #拷贝并回复
         for leader in self.client.leaders:
             msg.to = 1
             self.client.sendMessage(msg)  #给领导发消息
         self.notifyClient(message)  #通知自己
         return True
     raise Exception("并非预期的状态与命令")
Ejemplo n.º 4
0
 def doTransition(self, message):
     # 过度
     # 根据状态机运行协议
     if self.state == PaxosLeaderProtocol.STATE_PROPOSED:
         if message.command == Message.MSG_ACCEPTOR_AGREE:  #同意协议
             self.agreecount += 1
             if self.agreecount >= self.leader.getQuorumSize():  #选举
                 print(u"达成协议的法定人数,最后的价值回答是:%s" % message.value)
                 if message.value != None:
                     if message.sequence[0] > self.highestseen[0] or (
                             message.sequence[0] == self.highestseen[0]
                             and message.sequence[1] > self.highestseen[1]):
                         self.value = message.value  #数据同步
                         self.highestseen = message.sequence
                 self.state = PaxosLeaderProtocol.STATE_AGREED  #同意更新
                 # 发送同意消息
                 msg = Message(Message.MSG_ACCEPT)
                 msg.copyAsReply(message)
                 msg.value = self.value
                 msg.leaderID = msg.to
                 for s in self.leader.getAcceptors():  #广播消息
                     msg.to = s
                     self.leader.sendMessage(msg)
                 self.leader.notifyLeader(self, message)  #通知leader
             return True
         if message.command == Message.MSG_ACCEPTOR_REJECT:  #拒绝
             self.rejectcount += 1
             if self.rejectcount >= self.leader.getQuorumSize():
                 self.state = PaxosLeaderProtocol.STATE_REJECTED  #拒绝
                 self.leader.notifyLeader(self, message)  #传递消息
             return True
     if self.state == PaxosLeaderProtocol.STATE_AGREED:
         if message.command == Message.MSG_ACCEPTOR_ACCEPT:  #同意协议
             self.acceptcount += 1
             if self.acceptcount >= self.leader.getQuorumSize():  #投票
                 self.state = PaxosLeaderProtocol.STATE_ACCEPTED  #接受
                 self.leader.notifyLeader(self, message)
         if message.command == Message.MSG_ACCEPTOR_UNACCEPT:  #不同意的情况
             self.unacceptcount += 1
             if self.unacceptcount >= self.leader.getQuorumSize():  #投票
                 self.state = PaxosLeaderProtocol.STATE_UNACCEPTED
                 self.leader.notifyLeader(self, message)
     pass
Ejemplo n.º 5
0
    def doTranition(self, msg):
        # [start---2.2_1] AcceptorPropotal收到Proposer发出的Accept请求。按Paxos算法思想,这里需要判断请求版本号,当且仅当Acceptor之前承诺过的提议版本号最大值小于Accept请求版本号才会接受该Proposer提议。这里我们借助“先入为主”的思想简化问题,只要这时候协议状态为STATE_PROPOSAL_AGREED,就给所有Proposer广播消息表示自己确认接受该Proposer提议
        if self.state == PaxoAcceptorProtocol.STATE_PROPOSAL_AGREED \
                and msg.cmd == Message.MSG_ACCEPT:  #同意链接 并消息被接受
            self.state = PaxoAcceptorProtocol.STATE_PROPOSAL_ACCEPTED  #接受协议
            msg_accept = Message(Message.MSG_ACCEPTOR_ACCEPT)  #创造消息,用来表示该Acceptor最终接受了某个Proposer的提议
            msg_accept.copyAsReply(msg)

            #广播消息给所有提议者,告知自己最终接受了拿个Proposer的提议
            for proposer in self.client.proposers:
                msg_accept.to = proposer
                self.client.sendMsg(msg_accept)

            #[start - --2.2_1]AcceptorPropotal通知Acceptor更新InstanceRecord的值,到此时已有一个提议被一个Acceptor最终接受。
            self.notifyClient(msg)

            return True

        raise Exception(u"并非预期状态与命令")
Ejemplo n.º 6
0
 def recvProposal(self, message):  #收取协议
     if message.command == Message.MSG_EXT_PROPOSE:  #处理协议
         self.proposalID = message.proposalID  #协议编号
         (port, count) = self.client.getHighestAgreedProposal(
             message.instanceID)  #端口,协议内容的最高编号
         #编号检测处理消息协议 判断协议是不是最高
         if count<self.proposalID[0] or (count==self.proposalID[0] and \
                 port<self.proposalID[1]):
             self.state = PaxosAccepterProtocol.STATE_PROPOSAL_AGREED  #协议同意
             value = self.client.getInstanceValue(message.instanceID)  #抓取数据
             msg = Message(Message.MSG_ACCEPT)  #创建同意协议消息
             msg.copyAsReply(message)  #拷贝并回复
             msg.value = value  #保存值
             msg.sequence = (port, count)  #保存数据
             self.client.sendMessage(msg)  #发送消息
         else:
             self.state = PaxosAccepterProtocol.STATE_PROPOSAL_REJECTED  #拒绝状态
         return self.proposalID
     else:
         pass  #错误,重试
    def doTransition(self, message):  #过度 根据状态机运行协议
        if self.state == PaxosLeaderProtocol.STATE_PROPOSED:
            if message.command == Message.MSG_ACCEPTOR_ACCEPT:  #同意协议
                self.agreeCount += 1
                if self.agreeCount > self.leader.getQuorumSize():  #选举
                    if message.value != None:
                        if message.sequence[0]>self.highesteen[0] or \
                                (message.sequence[0]==self.highesteen[0] and \
                                        message.sequence[1]>self.highesteen[1]):
                            self.value = message.value  #数据同步
                            self.highesteen = message.sequence
                        self.state = PaxosLeaderProtocol.STATE_AGREED  #同意更新
                        #发送同意消息
                        msg = Message(Message.MSG_ACCEPT)
                        msg.copyAsReply(message)
                        msg.value = self.value
                        msg.leaderID = self.to
                        for server in self.leader.getAccepter():  #广播消息
                            msg.to = server
                            self.leader.sendMessage(msg)
                        self.leader.notifyLeader(self, message)  #通知leader
                return True
            if message.command == Message.MSG_ACCEPTOR_REJECT:  #拒绝
                self.rejectCount += 1
                if self.rejectCount >= self.leader.getQuorumSize():
                    self.state = PaxosLeaderProtocol.STATE_REJECTED
                    self.leader.notifyLeader(self, message)  #传递消息
                return True

        if self.state == PaxosLeaderProtocol.STATE_AGREED:
            if message.command == Message.MSG_ACCEPTOR_ACCEPT:  #同意协议
                self.accptCount += 1
                if self.accptCount >= self.leader.getQuorumSize():  #投票
                    self.state = PaxosLeaderProtocol.STATE_ACCEPTED  #接受
                    self.leader.notifyLeader(self, message)
            if message.command == Message.MSG_ACCEPTOR_UNACCEPT:  #不同意协议
                self.unacceptCount += 1
                if self.unacceptCount >= self.leader.getQuorumSize():  #投票
                    self.state = PaxosLeaderProtocol.STATE_UNACCEPTED
                    self.leader.notifyLeader(self, message)
Ejemplo n.º 8
0
    def doTranition(self, msg):
        #[start---1.5]ProposerPropotocal状态机函数收到一个MSG_ACCEPTOR_AGREE消息,此时表示有一个Acceptor承诺会接受我的请求。
        if self.state == PaxoProposerProtocol.STATE_PROPOSED:  #当前协议为提议状态提议
            if msg.cmd == Message.MSG_ACCEPTOR_AGREE:
                #许诺接受提议的计数器
                self.agreeCount += 1
                #[start---2.0_1]该条件下的代码会不断执行,直到许诺Proposer的数量超过半数,表示Prepare阶段基本结束。此时的Proposer向Acceptor集合发送Accept请求,请求Acceptor确认他们的许诺。
                if self.agreeCount > self.proposer.getQuorumCount():  #选举
                    print(u"达成协议的法定人数%d,最后的价值回答是:%s" % (self.agreeCount, msg.value))
                    if msg.value != None:
                        #判断版本号,根据版本高德更新记录的值
                        if msg.sequence[0] > self.highestseen[0] \
                            or (msg.sequence[0] == self.highestseen[0] \
                                and msg.sequence[1] > self.highestseen[1]):
                            self.value = msg.value  #数据同步
                            self.highestseen = msg.sequence

                    self.state == PaxoProposerProtocol.STATE_AGREED  #提议取得超半数Acceptor承诺,对应协议状态变为协议被许诺将接受

                    #[start---2.0_1]向Acceptor发送Accept请求,请求Acceptor确认许诺
                    msg_accept = Message(Message.MSG_ACCEPT)
                    msg_accept.copyAsReply(msg)
                    msg_accept.value = self.value
                    msg_accept.proposerID = msg.to
                    for server in self.proposer.getAcceptors():  #广播Accept请求
                        msg_accept.to = server
                        self.proposer.sendMsg(msg_accept)

                    #[start---2.0_2]通知其他提议者我的提议已经被半数Accept许诺将会被接受,使得其他Proposer知道Prepare阶段哪个提议获得的承诺最多。这样,在Commit阶段,他们可能通过改变提议来使系统尽快达到一致性。
                    self.proposer.notifyProposer(self, msg)

                return True
            if msg.cmd == Message.MSG_ACCEPTOR_REJECT:  #被拒绝
                self.rejectCount += 1
                if self.rejectCount > self.proposer.getQuorumCount():  #决策者拒绝数超过半数
                self.state = PaxoProposerProtocol.STATE_REJECTED
                self.proposer.notifyProposer(self, msg)

            return True


        if self.state == PaxoProposerProtocol.STATE_AGREED:  #同意状态
            #[start---2.4_1]ProposerProtocol收到一个Acceptor的最终确认消息(MSG_ACCEPTOR_ACCEPT),此时表示新增一个Acceptor最终接受了我的提议。但此时的协议状态仍然是STATE_AGREED状态,因为一个提议最终被系统接受必须先被超半数的Acceptor节点确认接受。
            if msg.cmd == Message.MSG_ACCEPTOR_ACCEPT:  #确认接受协议
                #确认接受当前协议的Acceptor计数器
                self.acceptCount += 1
                if self.acceptCount > self.proposer.getQuorumCount():  #提议被超半数Acceptor最终确认接受

                    #[start---2.4_2] STATE_AGREED条件下的代码会不断执行,直到最终接受提议的Acceptor超过半数。这时,协议状态由STATE_AGREED状态更新为最终被系统确认状态(STATE_ACCEPTED)。
                    self.state = PaxoProposerProtocol.STATE_ACCEPTED  #接受
                    #最后,最后,当前Proposerg更新自己的InstanceRecord记录
                    self.proposer.notifyProposer(self, msg)

            #当然,这里也有一种可能是被超过半数节点不接受,那么同样其他Proposer节点必有一个节点提议被接受。
            #该Proposer的提议最终不被Acceptor确认接受
            if msg.cmd == Message.MSG_ACCEPTOR_UNACCEPT: #不同意协议
                self.unacceptCount += 1
                if self.unacceptCount > self.proposer.getQuorumCount():
                    self.state = PaxoProposerProtocol.STATE_UNACCEPTED
                    self.proposer.notifyProposer(self, msg)

        pass