Search in sources :

Example 1 with Ballot

use of io.dingodb.raft.entity.Ballot in project dingo by dingodb.

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();
    if (!bl.init(conf, oldConf)) {
        LOG.error("Fail to init ballot.");
        return false;
    }
    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(io.dingodb.raft.entity.Ballot)

Example 2 with Ballot

use of io.dingodb.raft.entity.Ballot in project dingo by dingodb.

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?
    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;
        }
        // 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(io.dingodb.raft.entity.Ballot)

Aggregations

Ballot (io.dingodb.raft.entity.Ballot)2