def send_prepare(_self, proposal_id): ''' Broadcasts a Prepare message to all Acceptors ''' status("Preparing", proposal_id) msg = pxb.msg() msg.type = pxb.PREPARE msg.proposal_id = cPickle.dumps(proposal_id) self._broadcast_message(msg)
def send_heartbeat(_self, leader_proposal_id): ''' Sends a heartbeat message to all nodes ''' status("My heart still beats", leader_proposal_id) msg = pxb.msg() msg.type = pxb.HEARTBEAT msg.proposal_id = cPickle.dumps(leader_proposal_id) self._broadcast_message(msg)
def send_prepare_nack(_self, to_uid, proposal_id, promised_id): ''' Sends a Prepare Nack message for the proposal to the specified node ''' status("Prepare Nack", proposal_id, promised_id) msg = pxb.msg() msg.type = pxb.NACK_PREPARE msg.proposal_id = cPickle.dumps(proposal_id) msg.previous_id = cPickle.dumps(promised_id) self._send_message(to_uid, msg)
def send_accepted(_self, proposal_id, accepted_value): ''' Broadcasts an Accepted message to all Learners ''' status("Accepting", proposal_id, accepted_value) msg = pxb.msg() msg.type = pxb.ACCEPTED msg.proposal_id = cPickle.dumps(proposal_id) msg.value = cPickle.dumps(accepted_value) self._broadcast_message(msg)
def send_accept(_self, proposal_id, proposal_value): ''' Broadcasts an Accept! message to all Acceptors ''' status("Accept!ing", proposal_id, proposal_value) msg = pxb.msg() msg.type = pxb.ACCEPT msg.proposal_id = cPickle.dumps(proposal_id) msg.value = cPickle.dumps(proposal_value) self._broadcast_message(msg)
def send_accept_nack(_self, to_uid, proposal_id, promised_id): ''' Sends a Accept! Nack message for the proposal to the specified node ''' status("Accept Nack", proposal_id, promised_id) msg = pxb.msg() msg.type = pxb.NACK_ACCEPT msg.proposal_id = cPickle.dumps(proposal_id) msg.previous_id = cPickle.dumps(promised_id) self._send_message(to_uid, msg)
def do_paxos(self): """ Main Paxos loop """ for s,msg in self._get_messages(): if msg.proposal_id: proposal_id = paxos.functional.ProposalID._make(cPickle.loads(str(msg.proposal_id))) self.node.next_proposal_number = max(self.node.next_proposal_number, proposal_id.number + 1) if msg.previous_id: previous_id = paxos.functional.ProposalID._make(cPickle.loads(str(msg.previous_id))) if msg.type == pxb.PREPARE: self.node.recv_prepare(msg.from_uid, proposal_id) elif msg.type == pxb.PROMISE: previous_id = None accepted_value = cPickle.loads(str(msg.value)) self.node.recv_promise(msg.from_uid, proposal_id, previous_id, accepted_value) elif msg.type == pxb.ACCEPT: self.node.recv_accept_request(msg.from_uid, proposal_id, cPickle.loads(str(msg.value))) elif msg.type == pxb.ACCEPTED: self.node.recv_accepted(msg.from_uid, proposal_id, cPickle.loads(str(msg.value))) elif msg.type == pxb.NACK_PREPARE: self.node.recv_prepare_nack(msg.from_uid, proposal_id, previous_id) elif msg.type == pxb.NACK_ACCEPT: self.node.recv_accept_nack(msg.from_uid, proposal_id, previous_id) elif msg.type == pxb.HEARTBEAT: self.node.recv_heartbeat(msg.from_uid, proposal_id) elif msg.type == pxb.REQUEST: if self.node.leader: self.outbox.extend(cPickle.loads(str(msg.value))) else: status("Dropping request") else: raise NotImplementedError if not self.incr_instance: if self.outbox: if self.node.leader and not self.node.proposed_value: self.node.proposed_value = self.outbox self.node.prepare() elif not self.node.leader: msg = pxb.msg() msg.type = pxb.REQUEST msg.value = cPickle.dumps(self.outbox) self.outbox = [] self._broadcast_message(msg) self.node.persisted() if self.node.leader and self.node.next_hb <= time.time(): self.node.pulse() else: self.node = paxos.functional.HeartbeatNode(self.messenger, self.player, len(self.socks)/2 + 1, self.node.leader_uid) self.node.next_hb = time.time() self.instance += 1 self.incr_instance = False
def send_promise(_self, proposer_uid, proposal_id, previous_id, accepted_value): ''' Sends a Promise message to the specified Proposer ''' status("Promising", proposal_id, accepted_value) msg = pxb.msg() msg.type = pxb.PROMISE msg.proposal_id = cPickle.dumps(proposal_id) if previous_id: msg.previous_id = cPickle.dumps(previous_id) msg.value = cPickle.dumps(accepted_value) self._send_message(proposer_uid, msg)
def _get_messages(self): """ Read from all of the sockets """ msgs = [] for s in self.socks: if s: try: data = s.recv(1024) while data: msg = pxb.msg() msg.ParseFromString(data) if msg.instance > self.instance: print "OLD" msgs.append((s,msg)) data = s.recv(1024) except IOError: continue return msgs
def _get_messages(self): """ Read from all of the sockets """ msgs = [] for s in self.socks: if s: try: data = s.recv(1024) while data: msg = pxb.msg() msg.ParseFromString(data) if msg.instance > self.instance: print "OLD" msgs.append((s, msg)) data = s.recv(1024) except IOError: continue return msgs
def do_paxos(self): """ Main Paxos loop """ for s, msg in self._get_messages(): if msg.proposal_id: proposal_id = paxos.functional.ProposalID._make( cPickle.loads(str(msg.proposal_id))) self.node.next_proposal_number = max( self.node.next_proposal_number, proposal_id.number + 1) if msg.previous_id: previous_id = paxos.functional.ProposalID._make( cPickle.loads(str(msg.previous_id))) if msg.type == pxb.PREPARE: self.node.recv_prepare(msg.from_uid, proposal_id) elif msg.type == pxb.PROMISE: previous_id = None accepted_value = cPickle.loads(str(msg.value)) self.node.recv_promise(msg.from_uid, proposal_id, previous_id, accepted_value) elif msg.type == pxb.ACCEPT: self.node.recv_accept_request( msg.from_uid, proposal_id, cPickle.loads(str(msg.value))) elif msg.type == pxb.ACCEPTED: self.node.recv_accepted(msg.from_uid, proposal_id, cPickle.loads(str(msg.value))) elif msg.type == pxb.NACK_PREPARE: self.node.recv_prepare_nack(msg.from_uid, proposal_id, previous_id) elif msg.type == pxb.NACK_ACCEPT: self.node.recv_accept_nack(msg.from_uid, proposal_id, previous_id) elif msg.type == pxb.HEARTBEAT: self.node.recv_heartbeat(msg.from_uid, proposal_id) elif msg.type == pxb.REQUEST: if self.node.leader: self.outbox.extend(cPickle.loads(str(msg.value))) else: status("Dropping request") else: raise NotImplementedError if not self.incr_instance: if self.outbox: if self.node.leader and not self.node.proposed_value: self.node.proposed_value = self.outbox self.node.prepare() elif not self.node.leader: msg = pxb.msg() msg.type = pxb.REQUEST msg.value = cPickle.dumps(self.outbox) self.outbox = [] self._broadcast_message(msg) self.node.persisted() if self.node.leader and self.node.next_hb <= time.time(): self.node.pulse() else: self.node = paxos.functional.HeartbeatNode( self.messenger, self.player, len(self.socks) / 2 + 1, self.node.leader_uid) self.node.next_hb = time.time() self.instance += 1 self.incr_instance = False