Search in sources :

Example 1 with Timestamp

use of org.apache.ratis.util.Timestamp in project incubator-ratis by apache.

the class LeaderStateImpl method addSenders.

Collection<LogAppender> addSenders(Collection<RaftPeer> newPeers, long nextIndex, boolean attendVote) {
    final Timestamp t = Timestamp.currentTime().addTimeMs(-server.getMaxTimeoutMs());
    final List<LogAppender> newAppenders = newPeers.stream().map(peer -> {
        final FollowerInfo f = new FollowerInfoImpl(server.getMemberId(), peer, t, nextIndex, attendVote);
        LogAppender logAppender = server.newLogAppender(this, f);
        peerIdFollowerInfoMap.put(peer.getId(), f);
        raftServerMetrics.addFollower(peer.getId());
        logAppenderMetrics.addFollowerGauges(peer.getId(), f::getNextIndex, f::getMatchIndex, f::getLastRpcTime);
        return logAppender;
    }).collect(Collectors.toList());
    senders.addAll(newAppenders);
    return newAppenders;
}
Also used : Arrays(java.util.Arrays) TermIndex(org.apache.ratis.server.protocol.TermIndex) LongSupplier(java.util.function.LongSupplier) LeaderNotReadyException(org.apache.ratis.protocol.exceptions.LeaderNotReadyException) TransactionContext(org.apache.ratis.statemachine.TransactionContext) NotReplicatedException(org.apache.ratis.protocol.exceptions.NotReplicatedException) Map(java.util.Map) JavaUtils(org.apache.ratis.util.JavaUtils) ToLongFunction(java.util.function.ToLongFunction) ReconfigurationTimeoutException(org.apache.ratis.protocol.exceptions.ReconfigurationTimeoutException) Timestamp(org.apache.ratis.util.Timestamp) LogEntryProto(org.apache.ratis.proto.RaftProtos.LogEntryProto) RaftPeer(org.apache.ratis.protocol.RaftPeer) Predicate(java.util.function.Predicate) TransferLeadershipRequest(org.apache.ratis.protocol.TransferLeadershipRequest) Collection(java.util.Collection) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) AppendEntriesRequestProto(org.apache.ratis.proto.RaftProtos.AppendEntriesRequestProto) BlockingQueue(java.util.concurrent.BlockingQueue) CompletionException(java.util.concurrent.CompletionException) Collectors(java.util.stream.Collectors) Objects(java.util.Objects) ArrayBlockingQueue(java.util.concurrent.ArrayBlockingQueue) List(java.util.List) LogEntryBodyCase(org.apache.ratis.proto.RaftProtos.LogEntryProto.LogEntryBodyCase) Stream(java.util.stream.Stream) RaftClientReply(org.apache.ratis.protocol.RaftClientReply) LogAppender(org.apache.ratis.server.leader.LogAppender) RaftProperties(org.apache.ratis.conf.RaftProperties) Optional(java.util.Optional) TimeDuration(org.apache.ratis.util.TimeDuration) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) LogProtoUtils(org.apache.ratis.server.raftlog.LogProtoUtils) LogEntryHeader(org.apache.ratis.server.raftlog.LogEntryHeader) Preconditions(org.apache.ratis.util.Preconditions) RaftLog(org.apache.ratis.server.raftlog.RaftLog) SetConfigurationRequest(org.apache.ratis.protocol.SetConfigurationRequest) CollectionUtils(org.apache.ratis.util.CollectionUtils) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) LogAppenderMetrics(org.apache.ratis.server.metrics.LogAppenderMetrics) ArrayList(java.util.ArrayList) Message(org.apache.ratis.protocol.Message) NotLeaderException(org.apache.ratis.protocol.exceptions.NotLeaderException) ReplicationLevel(org.apache.ratis.proto.RaftProtos.ReplicationLevel) FollowerInfo(org.apache.ratis.server.leader.FollowerInfo) RaftServerMetricsImpl(org.apache.ratis.server.metrics.RaftServerMetricsImpl) LOG(org.apache.ratis.server.RaftServer.Division.LOG) Daemon(org.apache.ratis.util.Daemon) RaftPeerId(org.apache.ratis.protocol.RaftPeerId) RaftServerConfigKeys(org.apache.ratis.server.RaftServerConfigKeys) RaftClientRequest(org.apache.ratis.protocol.RaftClientRequest) IOException(java.io.IOException) CodeInjectionForTesting(org.apache.ratis.util.CodeInjectionForTesting) StartLeaderElectionRequestProto(org.apache.ratis.proto.RaftProtos.StartLeaderElectionRequestProto) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) FOLLOWER_GAP_RATIO_MAX_KEY(org.apache.ratis.server.RaftServerConfigKeys.Write.FOLLOWER_GAP_RATIO_MAX_KEY) CommitInfoProto(org.apache.ratis.proto.RaftProtos.CommitInfoProto) LeaderState(org.apache.ratis.server.leader.LeaderState) Collections(java.util.Collections) StartLeaderElectionReplyProto(org.apache.ratis.proto.RaftProtos.StartLeaderElectionReplyProto) LogAppender(org.apache.ratis.server.leader.LogAppender) Timestamp(org.apache.ratis.util.Timestamp) FollowerInfo(org.apache.ratis.server.leader.FollowerInfo)

Example 2 with Timestamp

use of org.apache.ratis.util.Timestamp in project incubator-ratis by apache.

the class LeaderStateImpl method checkProgress.

/**
 * So far we use a simple implementation for catchup checking:
 * 1. If the latest rpc time of the remote peer is before 3 * max_timeout,
 *    the peer made no progress for that long. We should fail the whole
 *    setConfiguration request.
 * 2. If the peer's matching index is just behind for a small gap, and the
 *    peer was updated recently (within max_timeout), declare the peer as
 *    caught-up.
 * 3. Otherwise the peer is making progressing. Keep waiting.
 */
private BootStrapProgress checkProgress(FollowerInfo follower, long committed) {
    Preconditions.assertTrue(!isAttendingVote(follower));
    final Timestamp progressTime = Timestamp.currentTime().addTimeMs(-server.getMaxTimeoutMs());
    final Timestamp timeoutTime = Timestamp.currentTime().addTimeMs(-3L * server.getMaxTimeoutMs());
    if (follower.getLastRpcResponseTime().compareTo(timeoutTime) < 0) {
        LOG.debug("{} detects a follower {} timeout ({}) for bootstrapping", this, follower, timeoutTime);
        return BootStrapProgress.NOPROGRESS;
    } else if (follower.getMatchIndex() + stagingCatchupGap > committed && follower.getLastRpcResponseTime().compareTo(progressTime) > 0 && follower.hasAttemptedToInstallSnapshot()) {
        return BootStrapProgress.CAUGHTUP;
    } else {
        return BootStrapProgress.PROGRESSING;
    }
}
Also used : Timestamp(org.apache.ratis.util.Timestamp)

Example 3 with Timestamp

use of org.apache.ratis.util.Timestamp in project incubator-ratis by apache.

the class LeaderElection method waitForResults.

private ResultAndTerm waitForResults(Phase phase, long electionTerm, int submitted, RaftConfigurationImpl conf, Executor voteExecutor) throws InterruptedException {
    final Timestamp timeout = Timestamp.currentTime().addTime(server.getRandomElectionTimeout());
    final Map<RaftPeerId, RequestVoteReplyProto> responses = new HashMap<>();
    final List<Exception> exceptions = new ArrayList<>();
    int waitForNum = submitted;
    Collection<RaftPeerId> votedPeers = new ArrayList<>();
    Collection<RaftPeerId> rejectedPeers = new ArrayList<>();
    Set<RaftPeerId> higherPriorityPeers = getHigherPriorityPeers(conf);
    while (waitForNum > 0 && shouldRun(electionTerm)) {
        final TimeDuration waitTime = timeout.elapsedTime().apply(n -> -n);
        if (waitTime.isNonPositive()) {
            if (conf.hasMajority(votedPeers, server.getId())) {
                // candidate pass vote
                return logAndReturn(phase, Result.PASSED, responses, exceptions);
            } else {
                return logAndReturn(phase, Result.TIMEOUT, responses, exceptions);
            }
        }
        try {
            final Future<RequestVoteReplyProto> future = voteExecutor.poll(waitTime);
            if (future == null) {
                // poll timeout, continue to return Result.TIMEOUT
                continue;
            }
            final RequestVoteReplyProto r = future.get();
            final RaftPeerId replierId = RaftPeerId.valueOf(r.getServerReply().getReplyId());
            final RequestVoteReplyProto previous = responses.putIfAbsent(replierId, r);
            if (previous != null) {
                if (LOG.isWarnEnabled()) {
                    LOG.warn("{} received duplicated replies from {}, the 2nd reply is ignored: 1st={}, 2nd={}", this, replierId, ServerStringUtils.toRequestVoteReplyString(previous), ServerStringUtils.toRequestVoteReplyString(r));
                }
                continue;
            }
            if (r.getShouldShutdown()) {
                return logAndReturn(phase, Result.SHUTDOWN, responses, exceptions);
            }
            if (r.getTerm() > electionTerm) {
                return logAndReturn(phase, Result.DISCOVERED_A_NEW_TERM, responses, exceptions, r.getTerm());
            }
            // If any peer with higher priority rejects vote, candidate can not pass vote
            if (!r.getServerReply().getSuccess() && higherPriorityPeers.contains(replierId)) {
                return logAndReturn(phase, Result.REJECTED, responses, exceptions);
            }
            // remove higher priority peer, so that we check higherPriorityPeers empty to make sure
            // all higher priority peers have replied
            higherPriorityPeers.remove(replierId);
            if (r.getServerReply().getSuccess()) {
                votedPeers.add(replierId);
                // If majority and all peers with higher priority have voted, candidate pass vote
                if (higherPriorityPeers.size() == 0 && conf.hasMajority(votedPeers, server.getId())) {
                    return logAndReturn(phase, Result.PASSED, responses, exceptions);
                }
            } else {
                rejectedPeers.add(replierId);
                if (conf.majorityRejectVotes(rejectedPeers)) {
                    return logAndReturn(phase, Result.REJECTED, responses, exceptions);
                }
            }
        } catch (ExecutionException e) {
            LogUtils.infoOrTrace(LOG, () -> this + " got exception when requesting votes", e);
            exceptions.add(e);
        }
        waitForNum--;
    }
    // received all the responses
    if (conf.hasMajority(votedPeers, server.getId())) {
        return logAndReturn(phase, Result.PASSED, responses, exceptions);
    } else {
        return logAndReturn(phase, Result.REJECTED, responses, exceptions);
    }
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) RequestVoteReplyProto(org.apache.ratis.proto.RaftProtos.RequestVoteReplyProto) Timestamp(org.apache.ratis.util.Timestamp) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) TimeDuration(org.apache.ratis.util.TimeDuration) RaftPeerId(org.apache.ratis.protocol.RaftPeerId) ExecutionException(java.util.concurrent.ExecutionException)

Example 4 with Timestamp

use of org.apache.ratis.util.Timestamp in project incubator-ratis by apache.

the class TestClientProtoUtils method runTestToRaftClientRequestProto.

void runTestToRaftClientRequestProto(int n, SizeInBytes messageSize) throws Exception {
    final ClientId clientId = ClientId.randomId();
    final RaftPeerId leaderId = RaftPeerId.valueOf("s0");
    final RaftGroupId groupId = RaftGroupId.randomId();
    TimeDuration toProto = TimeDuration.ZERO;
    TimeDuration toRequest = TimeDuration.ZERO;
    for (int i = 0; i < n; i++) {
        final ByteString bytes = newByteString(messageSize.getSizeInt(), i);
        final RaftClientRequest request = RaftClientRequest.newBuilder().setClientId(clientId).setServerId(leaderId).setGroupId(groupId).setCallId(1).setMessage(() -> bytes).setType(RaftClientRequest.writeRequestType()).build();
        final Timestamp startTime = Timestamp.currentTime();
        final RaftClientRequestProto proto = ClientProtoUtils.toRaftClientRequestProto(request);
        final TimeDuration p = startTime.elapsedTime();
        final RaftClientRequest computed = ClientProtoUtils.toRaftClientRequest(proto);
        final TimeDuration r = startTime.elapsedTime().subtract(p);
        Assert.assertEquals(request.getMessage().getContent(), computed.getMessage().getContent());
        toProto = toProto.add(p);
        toRequest = toRequest.add(r);
    }
    System.out.printf("%nmessageSize=%s, n=%d%n", messageSize, n);
    print("toProto  ", toProto, n);
    print("toRequest", toRequest, n);
}
Also used : RaftClientRequest(org.apache.ratis.protocol.RaftClientRequest) ByteString(org.apache.ratis.thirdparty.com.google.protobuf.ByteString) ClientId(org.apache.ratis.protocol.ClientId) RaftClientRequestProto(org.apache.ratis.proto.RaftProtos.RaftClientRequestProto) RaftGroupId(org.apache.ratis.protocol.RaftGroupId) TimeDuration(org.apache.ratis.util.TimeDuration) RaftPeerId(org.apache.ratis.protocol.RaftPeerId) Timestamp(org.apache.ratis.util.Timestamp)

Example 5 with Timestamp

use of org.apache.ratis.util.Timestamp in project incubator-ratis by apache.

the class RaftBasicTests method testRequestTimeout.

public static void testRequestTimeout(boolean async, MiniRaftCluster cluster, Logger LOG) throws Exception {
    waitForLeader(cluster);
    final Timestamp startTime = Timestamp.currentTime();
    try (final RaftClient client = cluster.createClient()) {
        // Get the next callId to be used by the client
        final ClientInvocationId invocationId = RaftClientTestUtil.getClientInvocationId(client);
        // Create an entry corresponding to the callId and clientId
        // in each server's retry cache.
        cluster.getServerAliveStream().forEach(raftServer -> RetryCacheTestUtil.getOrCreateEntry(raftServer, invocationId));
        // The retry is successful when the retry cache entry for the corresponding callId and clientId expires.
        if (async) {
            CompletableFuture<RaftClientReply> replyFuture = client.async().send(new SimpleMessage("abc"));
            replyFuture.get();
        } else {
            client.io().send(new SimpleMessage("abc"));
        }
        // Eventually the request would be accepted by the server
        // when the retry cache entry is invalidated.
        // The duration for which the client waits should be more than the retryCacheExpiryDuration.
        final TimeDuration duration = startTime.elapsedTime();
        TimeDuration retryCacheExpiryDuration = RaftServerConfigKeys.RetryCache.expiryTime(cluster.getProperties());
        Assert.assertTrue(duration.compareTo(retryCacheExpiryDuration) >= 0);
    }
}
Also used : RaftClientReply(org.apache.ratis.protocol.RaftClientReply) SimpleMessage(org.apache.ratis.RaftTestUtil.SimpleMessage) TimeDuration(org.apache.ratis.util.TimeDuration) ClientInvocationId(org.apache.ratis.protocol.ClientInvocationId) Timestamp(org.apache.ratis.util.Timestamp) RaftClient(org.apache.ratis.client.RaftClient)

Aggregations

Timestamp (org.apache.ratis.util.Timestamp)11 RaftPeerId (org.apache.ratis.protocol.RaftPeerId)5 IOException (java.io.IOException)4 RaftClientReply (org.apache.ratis.protocol.RaftClientReply)4 TimeDuration (org.apache.ratis.util.TimeDuration)4 ArrayList (java.util.ArrayList)3 RaftClient (org.apache.ratis.client.RaftClient)3 RaftClientRequest (org.apache.ratis.protocol.RaftClientRequest)3 HashMap (java.util.HashMap)2 List (java.util.List)2 Optional (java.util.Optional)2 CompletableFuture (java.util.concurrent.CompletableFuture)2 TimeUnit (java.util.concurrent.TimeUnit)2 RaftProperties (org.apache.ratis.conf.RaftProperties)2 RaftPeer (org.apache.ratis.protocol.RaftPeer)2 Timer (com.codahale.metrics.Timer)1 Arrays (java.util.Arrays)1 Collection (java.util.Collection)1 Collections (java.util.Collections)1 Iterator (java.util.Iterator)1