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)
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)
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)
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)