def do_JOIN(self, requester): # three is the minimum membership for a working cluster, so don't # respond until then, but don't expand the peers list beyond 3 if len(self.peers) < 3: self.peers.add(requester) if len(self.peers) < 3: return # otherwise, we have a cluster, but don't welcome any nodes not # part of that cluster (the cluster can do that itself) if requester not in self.peers: return peer_history = dict((sl, self.peers) for sl in range(0, protocol.ALPHA)) self.send( self.peers, "WELCOME", state=self.initial_state, slot_num=protocol.ALPHA, decisions=defaultlist(), viewid=0, peers=list(self.peers), peer_history=peer_history.copy(), ) # stick around for long enough that we don't hear any new JOINs from # the newly formed cluster if self.exit_timer: self.cancel_timer(self.exit_timer) self.exit_timer = self.set_timer(protocol.JOIN_RETRANSMIT * 2, self.stop)
def scout_finished(self, adopted, ballot_num, pvals): self.scout = None if adopted: # pvals is a defaultlist of (slot, proposal) by ballot num; we need the # highest ballot number for each slot. TODO: this is super # inefficient! last_by_slot = defaultlist() for b, s in reversed(sorted(pvals.keys())): p = pvals[b, s] if last_by_slot[s] is None: last_by_slot[s] = p for s, p in enumerate(last_by_slot): if p is not None: self.proposals[s] = p # re-spawn commanders for any potentially outstanding proposals for view_slot in sorted(self.peer_history): slot = view_slot + ALPHA if self.proposals[slot] is not None: self.spawn_commander(self.ballot_num, slot, self.proposals[slot], self.peer_history[view_slot]) # note that we don't re-spawn commanders here; if there are undecided # proposals, the replicas will re-propose self.logger.info("leader becoming active") self.active = True else: self.preempted(ballot_num)
def do_JOIN(self, requester): # three is the minimum membership for a working cluster, so don't # respond until then, but don't expand the peers list beyond 3 if len(self.peers) < 3: self.peers.add(requester) if len(self.peers) < 3: return # otherwise, we have a cluster, but don't welcome any nodes not # part of that cluster (the cluster can do that itself) if requester not in self.peers: return self.send(self.peers, 'WELCOME', state=self.initial_state, slot_num=1, decisions=defaultlist(), viewid=0, peers=list(self.peers)) # stick around for long enough that we don't hear any new JOINs from # the newly formed cluster if self.exit_timer: self.cancel_timer(self.exit_timer) self.exit_timer = self.set_timer(protocol.JOIN_RETRANSMIT * 2, self.stop)
def __init__(self, member, unique_id, commander_cls=Commander, scout_cls=Scout): super(Leader, self).__init__(member) self.ballot_num = Ballot(0, unique_id) self.active = False self.proposals = defaultlist() self.commander_cls = commander_cls self.commanders = {} self.scout_cls = scout_cls self.scout = None self.peers = None
def start(self, state, slot_num, decisions, viewid, peers): self.state = state self.slot_num = slot_num # next slot num for a proposal (may lead slot_num) self.next_slot = slot_num self.decisions = defaultlist(decisions) self.viewid = viewid self.peers = peers self.peers_down = set() self.repropose()
def start(self, state, slot_num, decisions, viewid, peers, peer_history): self.state = state self.slot_num = slot_num # next slot num for a proposal (may lead slot_num) self.next_slot = slot_num self.decisions = defaultlist(decisions) self.viewid = viewid self.peers = peers self.peers_down = set() self.peer_history = peer_history self.welcome_peers = set() assert decisions[slot_num] is None self.catchup()
def scout_finished(self, adopted, ballot_num, pvals): self.scout = None if adopted: # pvals is a defaultlist of (slot, proposal) by ballot num; we need the # highest ballot number for each slot. TODO: this is super # inefficient! last_by_slot = defaultlist() for b, s in reversed(sorted(pvals.keys())): p = pvals[b, s] if last_by_slot[s] is None: last_by_slot[s] = p for s, p in enumerate(last_by_slot): if p is not None: self.proposals[s] = p for s, p in enumerate(self.proposals): if p is not None: self.spawn_commander(ballot_num, s, p) self.logger.info("leader becoming active") self.active = True else: self.preempted(ballot_num)
def __init__(self, member, execute_fn): super(Replica, self).__init__(member) self.execute_fn = execute_fn self.proposals = defaultlist() self.viewchange_proposal = None