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 )

Python Setter/Getter - Property Decorator

위 코드에서 아래의 경우:

@property
def complete(self):
    return self.final_proposal_id is not None

클래스 내의 변수로 Getter를 설정한 것과 동일하다. 아래의 글을 참고한다.

[파이썬] property 사용법 (함수/데코레이터)

Code Analysis: 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 버전의 코드를 보자.