Search in sources :

Example 1 with Ballot

use of org.apache.ignite.raft.jraft.entity.Ballot in project ignite-3 by apache.

the class BallotBox method commitAt.

/**
 * Called by leader, otherwise the behavior is undefined Set logs in [first_log_index, last_log_index] are stable at
 * |peer|.
 */
public boolean commitAt(final long firstLogIndex, final long lastLogIndex, final PeerId peer) {
    // TODO use lock-free algorithm here? https://issues.apache.org/jira/browse/IGNITE-14832
    final long stamp = this.stampedLock.writeLock();
    long lastCommittedIndex = 0;
    try {
        if (this.pendingIndex == 0) {
            return false;
        }
        if (lastLogIndex < this.pendingIndex) {
            return true;
        }
        if (lastLogIndex >= this.pendingIndex + this.pendingMetaQueue.size()) {
            throw new ArrayIndexOutOfBoundsException();
        }
        final long startAt = Math.max(this.pendingIndex, firstLogIndex);
        Ballot.PosHint hint = new Ballot.PosHint();
        for (long logIndex = startAt; logIndex <= lastLogIndex; logIndex++) {
            final Ballot bl = this.pendingMetaQueue.get((int) (logIndex - this.pendingIndex));
            hint = bl.grant(peer, hint);
            if (bl.isGranted()) {
                lastCommittedIndex = logIndex;
            }
        }
        if (lastCommittedIndex == 0) {
            return true;
        }
        // TODO asch investigate https://issues.apache.org/jira/browse/IGNITE-14832.
        // When removing a peer off the raft group which contains even number of
        // peers, the quorum would decrease by 1, e.g. 3 of 4 changes to 2 of 3. In
        // this case, the log after removal may be committed before some previous
        // logs, since we use the new configuration to deal the quorum of the
        // removal request, we think it's safe to commit all the uncommitted
        // previous logs, which is not well proved right now
        this.pendingMetaQueue.removeFromFirst((int) (lastCommittedIndex - this.pendingIndex) + 1);
        LOG.debug("Committed log fromIndex={}, toIndex={}.", this.pendingIndex, lastCommittedIndex);
        this.pendingIndex = lastCommittedIndex + 1;
        this.lastCommittedIndex = lastCommittedIndex;
    } finally {
        this.stampedLock.unlockWrite(stamp);
    }
    this.waiter.onCommitted(lastCommittedIndex);
    return true;
}
Also used : Ballot(org.apache.ignite.raft.jraft.entity.Ballot)

Example 2 with Ballot

use of org.apache.ignite.raft.jraft.entity.Ballot in project ignite-3 by apache.

the class BallotBox method appendPendingTask.

/**
 * Called by leader, otherwise the behavior is undefined Store application context before replication.
 *
 * @param conf current configuration
 * @param oldConf old configuration
 * @param done callback
 * @return returns true on success
 */
public boolean appendPendingTask(final Configuration conf, final Configuration oldConf, final Closure done) {
    final Ballot bl = new Ballot();
    bl.init(conf, oldConf);
    final long stamp = this.stampedLock.writeLock();
    try {
        if (this.pendingIndex <= 0) {
            LOG.error("Fail to appendingTask, pendingIndex={}.", this.pendingIndex);
            return false;
        }
        this.pendingMetaQueue.add(bl);
        this.closureQueue.appendPendingClosure(done);
        return true;
    } finally {
        this.stampedLock.unlockWrite(stamp);
    }
}
Also used : Ballot(org.apache.ignite.raft.jraft.entity.Ballot)

Aggregations

Ballot (org.apache.ignite.raft.jraft.entity.Ballot)2