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
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
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("并非预期的状态与命令")
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
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"并非预期状态与命令")
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)
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