Exemple #1
0
    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)
Exemple #2
0
 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)
Exemple #3
0
    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)
Exemple #4
0
 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
Exemple #5
0
    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()
Exemple #6
0
    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()
Exemple #7
0
 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)
Exemple #8
0
 def __init__(self, member, execute_fn):
     super(Replica, self).__init__(member)
     self.execute_fn = execute_fn
     self.proposals = defaultlist()
     self.viewchange_proposal = None