Пример #1
0
def twophase(db):
    state = 'waiting'
    hnum = 0
    nreceives = 0
    client = None
    request_q = deque()

    while True:
        if len(request_q) > 0 and state == 'waiting':
            data, sock, addr = request_q.popleft()
        else:
            data, sock, addr = (yield)

        if 'request' in data:
            if state != 'waiting':
                request_q.append((data, sock, addr))
                continue
            # we have been chosen as the coordinator
            # we need to check with all acceptors
            print 'coordinator received request, preparing %s' % str(data)
            client = addr
            state = 'preparing'
            nreceives = 0
            prep_msg = json.dumps({
                'protocol': '2pc',
                'prepare': data['request'],
                'i': hnum + 1
            })
            bcast(sock, prep_msg)
        elif state == 'preparing':
            if 'promise' in data:
                nreceives += 1
                if nreceives == len(servers):
                    print 'got n promises, moving on'
                    state = 'accepting'
                    nreceives = 0
                    accept_msg = json.dumps({
                        'protocol': '2pc',
                        'accept': data['promise'],
                        'i': hnum
                    })
                    bcast(sock, accept_msg)
            elif 'nack' in data:
                state = 'waiting'
                nreceives = 0
        elif state == 'accepting':
            if 'accepted' in data:
                nreceives += 1
                if nreceives == len(servers):
                    print 'successfully got n accepts'
                    success_msg = json.dumps({
                        'protocol': '2pc',
                        'success': True
                    })
                    sock.sendto(success_msg, client)
                    state = 'waiting'
                    nreceives = 0
                    client = None
            elif 'nack' in data:
                state = 'waiting'
                nreceives = 0

        if 'prepare' in data:
            if data['i'] > hnum:
                hnum = data['i']
                response = json.dumps({
                    'protocol': '2pc',
                    'promise': data['prepare'],
                    'i': data['i']
                })
            else:
                response = json.dumps({'protocol': '2pc', 'nack': data['i']})
            sock.sendto(response, addr)
        elif 'accept' in data:
            if data['i'] == hnum:
                learner.send(data['accept'])
                response = json.dumps({
                    'protocol': '2pc',
                    'accepted': data['accept'],
                    'i': hnum
                })
            else:
                response = json.dumps({'protocol': '2pc', 'nack': data['i']})
            sock.sendto(response, addr)
Пример #2
0
def twophase(db):
    state = 'waiting'
    hnum = 0
    nreceives = 0
    client = None
    request_q = deque()

    while True:
        if len(request_q) > 0 and state == 'waiting':
            data, sock, addr = request_q.popleft()
        else:
            data, sock, addr = (yield)

        if 'request' in data:
            if state != 'waiting':
                request_q.append((data, sock, addr))
                continue
            # we have been chosen as the coordinator
            # we need to check with all acceptors
            print 'coordinator received request, preparing %s' % str(data)
            client = addr
            state = 'preparing'
            nreceives = 0
            prep_msg = json.dumps({'protocol':'2pc',
                                   'prepare':data['request'],
                                   'i':hnum + 1})
            bcast(sock, prep_msg)
        elif state == 'preparing':
            if 'promise' in data:
                nreceives += 1
                if nreceives == len(servers):
                    print 'got n promises, moving on'
                    state = 'accepting'
                    nreceives = 0
                    accept_msg = json.dumps({'protocol':'2pc',
                                             'accept':data['promise'],
                                             'i':hnum})
                    bcast(sock, accept_msg)
            elif 'nack' in data:
                state = 'waiting'
                nreceives = 0
        elif state == 'accepting':
            if 'accepted' in data:
                nreceives += 1
                if nreceives  == len(servers):
                    print 'successfully got n accepts'
                    success_msg = json.dumps({'protocol':'2pc',
                                              'success':True})
                    sock.sendto(success_msg, client)
                    state = 'waiting'
                    nreceives = 0
                    client = None
            elif 'nack' in data:
                state = 'waiting'
                nreceives = 0

        if 'prepare' in data:
            if data['i'] > hnum:
                hnum = data['i']
                response = json.dumps({'protocol':'2pc',
                                       'promise':data['prepare'],
                                       'i':data['i']})
            else:
                response = json.dumps({'protocol':'2pc',
                                       'nack':data['i']})
            sock.sendto(response, addr)
        elif 'accept' in data:
            if data['i'] == hnum:
                learner.send(data['accept'])
                response = json.dumps({'protocol':'2pc',
                                       'accepted':data['accept'],
                                       'i':hnum})
            else:
                response = json.dumps({'protocol':'2pc',
                                       'nack':data['i']})
            sock.sendto(response, addr)
Пример #3
0
def paxos(learner):
    state = 'waiting'
    hnum = 0
    nreceives = 0
    client = None
    request_q = deque()
    current_i = None

    while True:
        if len(request_q) > 0 and state == 'waiting':
            # adds fifo semantics to system
            data, sock, addr = request_q.popleft()
        else:
            data, sock, addr = (yield)

        if 'request' in data:
            if state != 'waiting':
                request_q.append((data, sock, addr))
                log_warn('queue contains %s elements' % len(request_q))
                continue
            # we have been chosen as the proposer
            # we need to check with all acceptors
            log_verbose('coordinator received request, preparing %s' %
                        str(data))
            client = addr
            state = 'preparing'
            nreceives = 0
            current_i = hnum + 1
            prep_msg = json.dumps({
                'protocol': 'paxos',
                'prepare': data['request'],
                'i': hnum + 1
            })
            bcast(sock, prep_msg)
        elif state == 'preparing':
            if 'promise' in data and data['i'] == current_i:
                nreceives += 1
                if nreceives > (len(servers) / 2):
                    log_verbose('got more than n/2 promises, moving on')
                    state = 'accepting'
                    nreceives = 0
                    accept_msg = json.dumps({
                        'protocol': 'paxos',
                        'accept': data['promise'],
                        'i': hnum
                    })
                    bcast(sock, accept_msg)
            elif 'nack' in data and data['i'] != current_i:
                log_warn('caught (and ignored) old nack: %s\tcurrent i: %s' %
                         (data['i'], current_i))
            elif 'nack' in data and data['i'] == current_i:
                log_warn('falling back to waiting state from preparing')
                log_fail('nack id: %s\thnum: %s' % (data['i'], hnum))
                state = 'waiting'
                nreceives = 0
        elif state == 'accepting':
            if 'accepted' in data and data['i'] == current_i:
                nreceives += 1
                if nreceives > (len(servers) / 2):
                    log_verbose('successfully got more than n/2 accepts')
                    success_msg = json.dumps({
                        'protocol': 'paxos',
                        'success': True
                    })
                    sock.sendto(success_msg, client)
                    state = 'waiting'
                    nreceives = 0
                    current_i = None
                    client = None
            elif 'nack' in data and data['i'] != current_i:
                log_warn('caught (and ignored) old nack: %s\tcurrent i: %s' %
                         (data['i'], current_i))
            elif 'nack' in data and data['i'] == current_i:
                log_warn('falling back to waiting state from accepting')
                log_fail('possible inconsistency')
                log_fail('nack id: %s\thnum: %s' % (data['i'], hnum))
                state = 'waiting'
                nreceives = 0

        if 'prepare' in data:
            if data['i'] > hnum:
                hnum = data['i']
                response = json.dumps({
                    'protocol': 'paxos',
                    'promise': data['prepare'],
                    'i': data['i']
                })
            else:
                log_warn('got prepare for number less than hnum')
                response = json.dumps({'protocol': 'paxos', 'nack': data['i']})
            sock.sendto(response, addr)
        elif 'accept' in data:
            if data['i'] == hnum:
                learner.send(data['accept'])
                response = json.dumps({
                    'protocol': 'paxos',
                    'accepted': data['accept'],
                    'i': hnum
                })
            else:
                log_warn('got accept for number other than hnum')
                log_fail('possible inconsistency')
                response = json.dumps({'protocol': 'paxos', 'nack': data['i']})
            sock.sendto(response, addr)
Пример #4
0
def paxos(learner):
    state = "waiting"
    hnum = 0
    nreceives = 0
    client = None
    request_q = deque()
    current_i = None

    while True:
        if len(request_q) > 0 and state == "waiting":
            # adds fifo semantics to system
            data, sock, addr = request_q.popleft()
        else:
            data, sock, addr = (yield)

        if "request" in data:
            if state != "waiting":
                request_q.append((data, sock, addr))
                log_warn("queue contains %s elements" % len(request_q))
                continue
            # we have been chosen as the proposer
            # we need to check with all acceptors
            log_verbose("coordinator received request, preparing %s" % str(data))
            client = addr
            state = "preparing"
            nreceives = 0
            current_i = hnum + 1
            prep_msg = json.dumps({"protocol": "paxos", "prepare": data["request"], "i": hnum + 1})
            bcast(sock, prep_msg)
        elif state == "preparing":
            if "promise" in data and data["i"] == current_i:
                nreceives += 1
                if nreceives > (len(servers) / 2):
                    log_verbose("got more than n/2 promises, moving on")
                    state = "accepting"
                    nreceives = 0
                    accept_msg = json.dumps({"protocol": "paxos", "accept": data["promise"], "i": hnum})
                    bcast(sock, accept_msg)
            elif "nack" in data and data["i"] != current_i:
                log_warn("caught (and ignored) old nack: %s\tcurrent i: %s" % (data["i"], current_i))
            elif "nack" in data and data["i"] == current_i:
                log_warn("falling back to waiting state from preparing")
                log_fail("nack id: %s\thnum: %s" % (data["i"], hnum))
                state = "waiting"
                nreceives = 0
        elif state == "accepting":
            if "accepted" in data and data["i"] == current_i:
                nreceives += 1
                if nreceives > (len(servers) / 2):
                    log_verbose("successfully got more than n/2 accepts")
                    success_msg = json.dumps({"protocol": "paxos", "success": True})
                    sock.sendto(success_msg, client)
                    state = "waiting"
                    nreceives = 0
                    current_i = None
                    client = None
            elif "nack" in data and data["i"] != current_i:
                log_warn("caught (and ignored) old nack: %s\tcurrent i: %s" % (data["i"], current_i))
            elif "nack" in data and data["i"] == current_i:
                log_warn("falling back to waiting state from accepting")
                log_fail("possible inconsistency")
                log_fail("nack id: %s\thnum: %s" % (data["i"], hnum))
                state = "waiting"
                nreceives = 0

        if "prepare" in data:
            if data["i"] > hnum:
                hnum = data["i"]
                response = json.dumps({"protocol": "paxos", "promise": data["prepare"], "i": data["i"]})
            else:
                log_warn("got prepare for number less than hnum")
                response = json.dumps({"protocol": "paxos", "nack": data["i"]})
            sock.sendto(response, addr)
        elif "accept" in data:
            if data["i"] == hnum:
                learner.send(data["accept"])
                response = json.dumps({"protocol": "paxos", "accepted": data["accept"], "i": hnum})
            else:
                log_warn("got accept for number other than hnum")
                log_fail("possible inconsistency")
                response = json.dumps({"protocol": "paxos", "nack": data["i"]})
            sock.sendto(response, addr)