Class KetchReplica

  • Direct Known Subclasses:
    LocalReplica, RemoteGitReplica

    public abstract class KetchReplica
    extends java.lang.Object
    A Ketch replica, either LocalReplica or RemoteGitReplica.

    Replicas can be either a stock Git replica, or a Ketch-aware replica.

    A stock Git replica has no special knowledge of Ketch and simply stores objects and references. Ketch communicates with the stock Git replica using the Git push wire protocol. The KetchLeader commits an agreed upon state by pushing all references to the Git replica, for example "refs/heads/master" is pushed during commit. Stock Git replicas use KetchReplica.CommitMethod.ALL_REFS to record the final state.

    Ketch-aware replicas understand the RefTree sent during the proposal and during commit are able to update their own reference space to match the state represented by the RefTree. Ketch-aware replicas typically use a RefTreeDatabase and KetchReplica.CommitMethod.TXN_COMMITTED to record the final state.

    KetchReplica instances are tightly coupled with a single KetchLeader. Some state may be accessed by the leader thread and uses the leader's own KetchLeader.lock to protect shared data.

    • Field Detail

      • log

        static final org.slf4j.Logger log
      • PEEL

        private static final byte[] PEEL
      • replicaName

        private final java.lang.String replicaName
      • minRetryMillis

        private final long minRetryMillis
      • maxRetryMillis

        private final long maxRetryMillis
      • running

        private final java.util.Map<java.lang.String,​ReceiveCommand> running
      • waiting

        private final java.util.Map<java.lang.String,​ReceiveCommand> waiting
      • txnAccepted

        private ObjectId txnAccepted
        Value known for "refs/txn/accepted".

        Raft literature refers to this as matchIndex.

      • txnCommitted

        private ObjectId txnCommitted
        Value known for "refs/txn/committed".

        Raft literature refers to this as commitIndex. In traditional Raft this is a state variable inside the follower implementation, but Ketch keeps it in the leader.

      • error

        private java.lang.String error
      • retryFuture

        private java.util.concurrent.Future<?> retryFuture
        Scheduled retry due to communication failure.
      • lastRetryMillis

        private long lastRetryMillis
      • retryAtMillis

        private long retryAtMillis
    • Constructor Detail

      • KetchReplica

        protected KetchReplica​(KetchLeader leader,
                               java.lang.String name,
                               ReplicaConfig cfg)
        Configure a replica representation.
        Parameters:
        leader - instance this replica follows.
        name - unique-ish name identifying this replica for debugging.
        cfg - how Ketch should treat the replica.
    • Method Detail

      • getSystem

        public KetchSystem getSystem()
        Get system configuration.
        Returns:
        system configuration.
      • getLeader

        public KetchLeader getLeader()
        Get leader instance this replica follows.
        Returns:
        leader instance this replica follows.
      • getName

        public java.lang.String getName()
        Get unique-ish name for debugging.
        Returns:
        unique-ish name for debugging.
      • describeForLog

        protected java.lang.String describeForLog()
        Get description of this replica for error/debug logging purposes.
        Returns:
        description of this replica for error/debug logging purposes.
      • getParticipation

        public KetchReplica.Participation getParticipation()
        Get how the replica participates in this Ketch system.
        Returns:
        how the replica participates in this Ketch system.
      • getCommitMethod

        public KetchReplica.CommitMethod getCommitMethod()
        Get how Ketch will commit to the repository.
        Returns:
        how Ketch will commit to the repository.
      • getCommitSpeed

        public KetchReplica.CommitSpeed getCommitSpeed()
        Get when Ketch will commit to the repository.
        Returns:
        when Ketch will commit to the repository.
      • shutdown

        protected void shutdown()
        Called by leader to perform graceful shutdown.

        Default implementation cancels any scheduled retry. Subclasses may add additional logic before or after calling super.shutdown().

        Called with KetchLeader.lock held by caller.

      • initialize

        void initialize​(java.util.Map<java.lang.String,​Ref> refs)
        Update the leader's view of the replica after a poll.

        Called with KetchLeader.lock held by caller.

        Parameters:
        refs - map of refs from the replica.
      • getTxnAccepted

        ObjectId getTxnAccepted()
      • hasAccepted

        boolean hasAccepted​(LogIndex id)
      • pushTxnAcceptedAsync

        void pushTxnAcceptedAsync​(Round round)
        Schedule a proposal round with the replica.

        Called with KetchLeader.lock held by caller.

        Parameters:
        round - current round being run by the leader.
      • shouldPushUnbatchedCommit

        boolean shouldPushUnbatchedCommit​(LogIndex committed,
                                          boolean leaderIdle)
      • pushCommitAsync

        void pushCommitAsync​(LogIndex committed)
      • prepareTxnCommitted

        private void prepareTxnCommitted​(java.util.List<ReceiveCommand> cmds,
                                         ObjectId committed)
      • runNextPushRequest

        private void runNextPushRequest()
        Determine the next push for this replica (if any) and start it.

        If the replica has successfully accepted the committed state of the leader, this method will push all references to the replica using the configured KetchReplica.CommitMethod.

        If the replica is KetchReplica.State.LAGGING this method will begin catch up by sending a more recent refs/txn/accepted.

        Must be invoked with KetchLeader.lock held by caller.

      • waitingForRetry

        private boolean waitingForRetry()
      • doRetryPush

        private void doRetryPush()
      • startPush

        protected abstract void startPush​(ReplicaPushRequest req)
        Begin executing a single push.

        This method must move processing onto another thread. Called with KetchLeader.lock held by caller.

        Parameters:
        req - the request to send to the replica.
      • afterPush

        void afterPush​(@Nullable
                       Repository repo,
                       ReplicaPushRequest req)
        Callback from ReplicaPushRequest upon success or failure.

        Acquires the KetchLeader.lock and updates the leader's internal knowledge about this replica to reflect what has been learned during a push to the replica. In some cases of divergence this method may take some time to determine how the replica has diverged; to reduce contention this is evaluated before acquiring the leader lock.

        Parameters:
        repo - local repository instance used by the push thread.
        req - push request just attempted.
      • blockingFetch

        protected abstract void blockingFetch​(Repository repo,
                                              ReplicaFetchRequest req)
                                       throws java.io.IOException
        Fetch objects from the remote using the calling thread.

        Called without KetchLeader.lock.

        Parameters:
        repo - local repository to fetch objects into.
        req - the request to fetch from a replica.
        Throws:
        java.io.IOException - communication with the replica was not possible.
      • prepareCommit

        protected java.util.Collection<ReceiveCommand> prepareCommit​(Repository git,
                                                                     java.util.Map<java.lang.String,​Ref> current,
                                                                     ObjectId committed)
                                                              throws java.io.IOException
        Build a list of commands to commit KetchReplica.CommitMethod.ALL_REFS.
        Parameters:
        git - local leader repository to read committed state from.
        current - all known references in the replica's repository. Typically this comes from a push advertisement.
        committed - state being pushed to refs/txn/committed.
        Returns:
        commands to update during commit.
        Throws:
        java.io.IOException - cannot read the committed state.
      • canDelete

        boolean canDelete​(Ref ref)