Exemple #1
0
 def __init__(self):
     """
     - ballotnumber: the highest ballotnumber Acceptor has encountered
     - accepted: all pvalues Acceptor has accepted thus far
     """
     Node.__init__(self, NODE_ACCEPTOR)
     if self.durable:
         self.file = open('concoordlog', 'a')
     self.ballotnumber = (0, '')
     self.last_accept_msg_id = -1
     self.accepted = PValueSet()
     self.objectsnapshot = (0, None)
Exemple #2
0
 def __init__(self):
     """
     - ballotnumber: the highest ballotnumber Acceptor has encountered
     - accepted: all pvalues Acceptor has accepted thus far
     """
     Node.__init__(self, NODE_ACCEPTOR)
     # self.file = open('concoordlog', 'a')
     self.ballotnumber = (0, 0)
     self.last_accept_msg_id = -1
     self.accepted = PValueSet()
     self.objectsnapshot = (0, None)
     if self.debug and False:
         profile_on()  # Turn profiling on!
Exemple #3
0
 def __init__(self):
     """
     - ballotnumber: the highest ballotnumber Acceptor has encountered
     - accepted: all pvalues Acceptor has accepted thus far
     """
     Node.__init__(self, NODE_ACCEPTOR)
     self.ballotnumber = (0,0)
     self.last_accept_msg_id = -1
     self.accepted = PValueSet()
     self.objectsnapshot = (0,None)
Exemple #4
0
 def __init__(self):
     """
     - ballotnumber: the highest ballotnumber Acceptor has encountered
     - accepted: all pvalues Acceptor has accepted thus far
     """
     Node.__init__(self, NODE_ACCEPTOR)
     if self.durable:
         self.file = open('concoordlog', 'a')
     self.ballotnumber = (0,'')
     self.last_accept_msg_id = -1
     self.accepted = PValueSet()
     self.objectsnapshot = (0,None)
Exemple #5
0
 def __init__(self):
     """
     - ballotnumber: the highest ballotnumber Acceptor has encountered
     - accepted: all pvalues Acceptor has accepted thus far
     """
     Node.__init__(self, NODE_ACCEPTOR)
     # self.file = open('concoordlog', 'a')
     self.ballotnumber = (0,0)
     self.last_accept_msg_id = -1
     self.accepted = PValueSet()
     self.objectsnapshot = (0,None)
     if self.debug and False:
         profile_on() # Turn profiling on!
Exemple #6
0
 def __init__(self, acceptors, ballotnumber, commandnumber, proposal):
     """ResponseCollector state
     - ballotnumber: ballotnumber for the corresponding msg
     - commandnumber: commandnumber for the corresponding msg
     - proposal: proposal for the corresponding msg
     - acceptors: group of acceptor nodes for the corresponding msg
     - sent: msgids for the messages that have been sent
     - received: dictionary that keeps <peer:reply> mappings
     - ntotal: # of acceptornodes for the corresponding msg
     - nquorum: # of accepts needed for success
     - possiblepvalueset: Set of pvalues collected from acceptors
     """
     self.ballotnumber = ballotnumber
     self.commandnumber = commandnumber
     self.proposal = proposal
     self.acceptors = acceptors
     self.receivedcount = 0
     self.ntotal = len(self.acceptors)
     self.nquorum = self.ntotal / 2 + 1
     self.possiblepvalueset = PValueSet()
Exemple #7
0
class Acceptor(Node):
    """
    Acceptor keeps track of past Paxos ballots. It supports garbage
    collection by keeping track of an object snapshot and trimming all
    previous ballots prior to the snapshot.
    """
    def __init__(self):
        """
        - ballotnumber: the highest ballotnumber Acceptor has encountered
        - accepted: all pvalues Acceptor has accepted thus far
        """
        Node.__init__(self, NODE_ACCEPTOR)
        if self.durable:
            self.file = open('concoordlog', 'a')
        self.ballotnumber = (0,0)
        self.last_accept_msg_id = -1
        self.accepted = PValueSet()
        self.objectsnapshot = (0,None)

    def msg_prepare(self, conn, msg):
        """
        MSG_PREPARE is accepted only if it carries a ballotnumber greater
        than the highest ballotnumber Acceptor has ever received.

        Replies:
        - MSG_PREPARE_ADOPTED carries the ballotnumber that is received and
        all pvalues accepted thus far.
        - MSG_PREPARE_PREEMPTED carries the highest ballotnumber Acceptor
        has seen and all pvalues accepted thus far.
        """
        # this ballot should be strictly higher than previously accepted ballots
        if msg.ballotnumber >= self.ballotnumber:
            if self.debug: self.logger.write("Paxos State",
                              "prepare received with acceptable ballotnumber %s"
                              % str(msg.ballotnumber))

            self.ballotnumber = msg.ballotnumber
            self.last_accept_msg_id = msg.id
            replymsg = create_message(MSG_PREPARE_ADOPTED, self.me,
                                      {FLD_BALLOTNUMBER: self.ballotnumber,
                                       FLD_INRESPONSETO: msg.ballotnumber,
                                       FLD_PVALUESET: self.accepted.pvalues})
        # or else it should be a precise duplicate of the last request
        # in this case we do nothing
        elif msg.ballotnumber == self.ballotnumber and \
                msg.id == self.last_accept_msg_id:
            if self.debug: self.logger.write("Paxos State","message received before: %s" % msg)
            return
        else:
            if self.debug: self.logger.write("Paxos State",
                              ("prepare received with non-acceptable "
                               "ballotnumber %s ") % (str(msg.ballotnumber),))
            self.last_accept_msg_id = msg.id
            replymsg = create_message(MSG_PREPARE_PREEMPTED, self.me,
                                      {FLD_BALLOTNUMBER: self.ballotnumber,
                                       FLD_INRESPONSETO: msg.ballotnumber,
                                       FLD_PVALUESET: self.accepted.pvalues})

        if self.debug: self.logger.write("Paxos State", "prepare responding with %s"
                          % str(replymsg))
        conn.send(replymsg)

    def msg_propose(self, conn, msg):
        """
        MSG_PROPOSE is accepted only if it carries a ballotnumber greater
        than the highest ballotnumber Acceptor has received.

        Replies:
        - MSG_PROPOSE_ACCEPT carries ballotnumber and commandnumber received.
        - MSG_PROPOSE_REJECT carries the highest ballotnumber Acceptor has
        seen and the commandnumber that is received.
        """
        if msg.ballotnumber >= self.ballotnumber:
            if self.debug: self.logger.write("Paxos State",
                              "propose received with acceptable ballotnumber %s"
                              % str(msg.ballotnumber))
            self.ballotnumber = msg.ballotnumber
            newpvalue = PValue(msg.ballotnumber,msg.commandnumber,msg.proposal)
            self.accepted.add(newpvalue)
            replymsg = create_message(MSG_PROPOSE_ACCEPT, self.me,
                                      {FLD_BALLOTNUMBER: self.ballotnumber,
                                       FLD_INRESPONSETO: msg.ballotnumber,
                                       FLD_COMMANDNUMBER: msg.commandnumber})
            conn.send(replymsg)
            if self.durable:
                self.file.write(str(newpvalue))
                os.fsync(self.file)
        else:
            if self.debug: self.logger.write("Paxos State",
                              "propose received with non-acceptable ballotnumber %s"
                              % str(msg.ballotnumber))
            replymsg = create_message(MSG_PROPOSE_REJECT, self.me,
                                      {FLD_BALLOTNUMBER: self.ballotnumber,
                                       FLD_INRESPONSETO: msg.ballotnumber,
                                       FLD_COMMANDNUMBER: msg.commandnumber})
            conn.send(replymsg)

    def msg_garbagecollect(self, conn, msg):
        if self.debug: self.logger.write("Paxos State",
                          "Doing garbage collection upto %d" % msg.commandnumber)
        success = self.accepted.truncateto(msg.commandnumber)
        if success:
            self.objectsnapshot = (msg.commandnumber,pickle.loads(msg.snapshot))
        else:
            if self.debug: self.logger.write("Garbage Collection Error",
                              "Garbege Collection failed.")

    def cmd_paxos(self, args):
        """
        Print the paxos state of the Acceptor.
        """
        keytuples = self.accepted.pvalues.keys()
        print sorted(keytuples, key=lambda keytuple: keytuple[0])

    def terminate_handler(self, signal, frame):
        self._graceexit()

    def _graceexit(self, exitcode=0):
        sys.stdout.flush()
        sys.stderr.flush()
        if self.debug: self.logger.close()
        os._exit(exitcode)
Exemple #8
0
class Acceptor(Node):
    """
    Acceptor keeps track of past Paxos ballots. It supports garbage
    collection by keeping track of an object snapshot and trimming all
    previous ballots prior to the snapshot.
    """
    def __init__(self):
        """
        - ballotnumber: the highest ballotnumber Acceptor has encountered
        - accepted: all pvalues Acceptor has accepted thus far
        """
        Node.__init__(self, NODE_ACCEPTOR)
        # self.file = open('concoordlog', 'a')
        self.ballotnumber = (0, 0)
        self.last_accept_msg_id = -1
        self.accepted = PValueSet()
        self.objectsnapshot = (0, None)
        if self.debug and False:
            profile_on()  # Turn profiling on!

    def msg_prepare(self, conn, msg):
        """
        MSG_PREPARE is accepted only if it carries a ballotnumber greater
        than the highest ballotnumber Acceptor has ever received.

        Replies:
        - MSG_PREPARE_ADOPTED carries the ballotnumber that is received and
        all pvalues accepted thus far.
        - MSG_PREPARE_PREEMPTED carries the highest ballotnumber Acceptor
        has seen and all pvalues accepted thus far.
        """
        # this ballot should be strictly higher than previously accepted ballots
        if msg.ballotnumber >= self.ballotnumber:
            if self.debug:
                self.logger.write(
                    "Paxos State",
                    "prepare received with acceptable ballotnumber %s" %
                    str(msg.ballotnumber))

            self.ballotnumber = msg.ballotnumber
            self.last_accept_msg_id = msg.id
            replymsg = create_message(
                MSG_PREPARE_ADOPTED, self.me, {
                    FLD_BALLOTNUMBER: self.ballotnumber,
                    FLD_INRESPONSETO: msg.ballotnumber,
                    FLD_PVALUESET: self.accepted.pvalues
                })
        # or else it should be a precise duplicate of the last request
        # in this case we do nothing
        elif msg.ballotnumber == self.ballotnumber and \
                msg.id == self.last_accept_msg_id:
            if self.debug:
                self.logger.write("Paxos State",
                                  "message received before: %s" % msg)
            return
        else:
            if self.debug:
                self.logger.write("Paxos State",
                                  ("prepare received with non-acceptable "
                                   "ballotnumber %s ") %
                                  (str(msg.ballotnumber), ))
            self.last_accept_msg_id = msg.id
            replymsg = create_message(
                MSG_PREPARE_PREEMPTED, self.me, {
                    FLD_BALLOTNUMBER: self.ballotnumber,
                    FLD_INRESPONSETO: msg.ballotnumber,
                    FLD_PVALUESET: self.accepted.pvalues
                })

        if self.debug:
            self.logger.write("Paxos State",
                              "prepare responding with %s" % str(replymsg))
        conn.send(replymsg)

    def msg_propose(self, conn, msg):
        """
        MSG_PROPOSE is accepted only if it carries a ballotnumber greater
        than the highest ballotnumber Acceptor has received.

        Replies:
        - MSG_PROPOSE_ACCEPT carries ballotnumber and commandnumber received.
        - MSG_PROPOSE_REJECT carries the highest ballotnumber Acceptor has
        seen and the commandnumber that is received.
        """
        if msg.ballotnumber >= self.ballotnumber:
            if self.debug:
                self.logger.write(
                    "Paxos State",
                    "propose received with acceptable ballotnumber %s" %
                    str(msg.ballotnumber))
            self.ballotnumber = msg.ballotnumber
            newpvalue = PValue(msg.ballotnumber, msg.commandnumber,
                               msg.proposal)
            self.accepted.add(newpvalue)
            replymsg = create_message(
                MSG_PROPOSE_ACCEPT, self.me, {
                    FLD_BALLOTNUMBER: self.ballotnumber,
                    FLD_INRESPONSETO: msg.ballotnumber,
                    FLD_COMMANDNUMBER: msg.commandnumber
                })
            conn.send(replymsg)
            # self.file.write(str(newpvalue))
        else:
            if self.debug:
                self.logger.write(
                    "Paxos State",
                    "propose received with non-acceptable ballotnumber %s" %
                    str(msg.ballotnumber))
            replymsg = create_message(
                MSG_PROPOSE_REJECT, self.me, {
                    FLD_BALLOTNUMBER: self.ballotnumber,
                    FLD_INRESPONSETO: msg.ballotnumber,
                    FLD_COMMANDNUMBER: msg.commandnumber
                })
            conn.send(replymsg)

    def msg_garbagecollect(self, conn, msg):
        if self.debug:
            self.logger.write(
                "Paxos State",
                "Doing garbage collection upto %d" % msg.commandnumber)
        success = self.accepted.truncateto(msg.commandnumber)
        if success:
            self.objectsnapshot = (msg.commandnumber,
                                   pickle.loads(msg.snapshot))
        else:
            if self.debug:
                self.logger.write("Garbage Collection Error",
                                  "Garbege Collection failed.")

    def cmd_paxos(self, args):
        """
        Print the paxos state of the Acceptor.
        """
        keytuples = self.accepted.pvalues.keys()
        print sorted(keytuples, key=lambda keytuple: keytuple[0])

    def terminate_handler(self, signal, frame):
        if self.debug and False:
            profile_off()  #turn profiling off
            print_profile_stats()
        self._graceexit()

    def _graceexit(self, exitcode=0):
        sys.stdout.flush()
        sys.stderr.flush()
        if self.debug: self.logger.close()
        os._exit(exitcode)
Exemple #9
0
class Acceptor(Node):
    """Acceptor keeps track of past Paxos ballots. It supports garbage collection by keeping track
    of an object snapshot and trimming all previous ballots prior to the snapshot.
    """
    def __init__(self):
        """
        - ballotnumber: the highest ballotnumber Acceptor has encountered
        - accepted: all pvalues Acceptor has accepted thus far
        """
        Node.__init__(self, NODE_ACCEPTOR)
        self.ballotnumber = (0,0)
        self.last_accept_msg_id = -1
        self.accepted = PValueSet()
        self.objectsnapshot = (0,None)
        
    def msg_prepare(self, conn, msg):
        """
        MSG_PREPARE is accepted only if it carries a ballotnumber greater
        than the highest ballotnumber Acceptor has ever received.

        Replies:
        - MSG_PREPARE_ADOPTED carries the ballotnumber that is received and all pvalues
        accepted thus far.
        - MSG_PREPARE_PREEMPTED carries the highest ballotnumber Acceptor has seen and all
        pvalues accepted thus far.
        """
        # this ballot should be strictly higher than previous ballots we have accepted,
        if msg.ballotnumber > self.ballotnumber:
            self.logger.write("Paxos State", "prepare received with acceptable ballotnumber %s" % str(msg.ballotnumber))
            self.ballotnumber = msg.ballotnumber
            self.last_accept_msg_id = msg.fullid()
            replymsg = PaxosMessage(MSG_PREPARE_ADOPTED,self.me,ballotnumber=self.ballotnumber,inresponsetoballotnumber=msg.ballotnumber,givenpvalueset=self.accepted)
        # or else it should be a precise duplicate of the last request, in which case we do nothing
        elif msg.ballotnumber == self.ballotnumber and msg.fullid() == self.last_accept_msg_id:
            return
        else:
            self.logger.write("Paxos State", "prepare received with non-acceptable ballotnumber %s for commandnumber %s" % (str(msg.ballotnumber), str(msg.commandnumber)))
            replymsg = PaxosMessage(MSG_PREPARE_PREEMPTED,self.me,ballotnumber=self.ballotnumber,inresponsetoballotnumber=msg.ballotnumber,givenpvalueset=self.accepted)
        self.logger.write("Paxos State", "prepare responding with %s" % str(replymsg))
        self.send(replymsg,peer=msg.source)

    def msg_propose(self, conn, msg):
        """
        MSG_PROPOSE is accepted only if it carries a ballotnumber greater
        than the highest ballotnumber Acceptor has received.

        Replies:
        - MSG_PROPOSE_ACCEPT carries the ballotnumber and the commandnumber that are received.
        - MSG_PROPOSE_REJECT carries the highest ballotnumber Acceptor has seen and the
        commandnumber that is received.
        """
        if msg.ballotnumber >= self.ballotnumber:
            self.logger.write("Paxos State", "propose received with acceptable ballotnumber %s" % str(msg.ballotnumber))
            self.ballotnumber = msg.ballotnumber
            newpvalue = PValue(msg.ballotnumber,msg.commandnumber,msg.proposal)
            self.accepted.add(newpvalue)
            replymsg = PaxosMessage(MSG_PROPOSE_ACCEPT,self.me,ballotnumber=self.ballotnumber,inresponsetoballotnumber=msg.ballotnumber,commandnumber=msg.commandnumber)
        else:
            self.logger.write("Paxos State", "propose received with non-acceptable ballotnumber %s" % str(msg.ballotnumber))
            replymsg = PaxosMessage(MSG_PROPOSE_REJECT,self.me,ballotnumber=self.ballotnumber,inresponsetoballotnumber=msg.ballotnumber,commandnumber=msg.commandnumber)
        self.send(replymsg,peer=msg.source)

    def msg_garbagecollect(self, conn, msg):
        self.logger.write("Paxos State", "Doing garbage collection upto %d" % msg.commandnumber)
        success = self.accepted.truncateto(msg.commandnumber)
        if success:
            self.objectsnapshot = (msg.commandnumber,msg.snapshot)
        else:
            self.logger.write("Garbage Collection Error", "Garbege Collection failed.")
        
    def cmd_paxos(self, args):
        """Shell command [paxos]: Print the paxos state of the Acceptor."""
        keytuples = self.accepted.pvalues.keys()
        print sorted(keytuples, key=lambda keytuple: keytuple[0])