Location: paxos/essential.py
class Learner (object):
quorum_size = None
proposals = None # maps proposal_id => [accept_count, retain_count, value]
acceptors = None # maps from_uid => last_accepted_proposal_id
final_value = None
final_proposal_id = None
@property
def complete(self):
return self.final_proposal_id is not None
def recv_accepted(self, from_uid, proposal_id, accepted_value):
'''
Called when an Accepted message is received from an acceptor
'''
if self.final_value is not None:
return # already done
if self.proposals is None:
self.proposals = dict()
self.acceptors = dict()
last_pn = self.acceptors.get(from_uid)
if not proposal_id > last_pn:
return # Old message
self.acceptors[ from_uid ] = proposal_id
if last_pn is not None:
oldp = self.proposals[ last_pn ]
oldp[1] -= 1
if oldp[1] == 0:
del self.proposals[ last_pn ]
if not proposal_id in self.proposals:
self.proposals[ proposal_id ] = [0, 0, accepted_value]
t = self.proposals[ proposal_id ]
assert accepted_value == t[2], 'Value mismatch for single proposal!'
t[0] += 1
t[1] += 1
if t[0] == self.quorum_size:
self.final_value = accepted_value
self.final_proposal_id = proposal_id
self.proposals = None
self.acceptors = None
self.messenger.on_resolution( proposal_id, accepted_value )
위 코드에서 아래의 경우:
@property
def complete(self):
return self.final_proposal_id is not None
클래스 내의 변수로 Getter를 설정한 것과 동일하다. 아래의 글을 참고한다.
oldp
코드를 읽다 보면 Learner
클래스의 recv_accepted
함수 중 이해가 되지 않는 부분이 있을 수 있다.
if last_pn is not None:
oldp = self.proposals[ last_pn ]
oldp[1] -= 1
if oldp[1] == 0:
del self.proposals[ last_pn ]
여기에서 oldp의 인덱스 1
은 무엇을 의미하는지 알 수 없다. Java
버전의 코드를 보자.