Search in sources :

Example 1 with ResourceUnavailableException

use of org.apache.ratis.protocol.exceptions.ResourceUnavailableException in project incubator-ratis by apache.

the class RaftClientImpl method handleIOException.

void handleIOException(RaftClientRequest request, IOException ioe, RaftPeerId newLeader, Consumer<RaftClientRequest> handler) {
    LOG.debug("{}: suggested new leader: {}. Failed {} with {}", clientId, newLeader, request, ioe);
    if (LOG.isTraceEnabled()) {
        LOG.trace("Stack trace", new Throwable("TRACE"));
    }
    Optional.ofNullable(handler).ifPresent(h -> h.accept(request));
    if (ioe instanceof LeaderNotReadyException || ioe instanceof ResourceUnavailableException) {
        return;
    }
    final RaftPeerId oldLeader = request.getServerId();
    final RaftPeerId curLeader = leaderId;
    final boolean stillLeader = oldLeader.equals(curLeader);
    if (newLeader == null && stillLeader) {
        newLeader = CollectionUtils.random(oldLeader, CollectionUtils.as(peers, RaftPeer::getId));
    }
    LOG.debug("{}: oldLeader={},  curLeader={}, newLeader={}", clientId, oldLeader, curLeader, newLeader);
    final boolean changeLeader = newLeader != null && stillLeader;
    final boolean reconnect = changeLeader || clientRpc.shouldReconnect(ioe);
    if (reconnect) {
        if (changeLeader && oldLeader.equals(leaderId)) {
            LOG.debug("{} {}: client change Leader from {} to {} ex={}", groupId, clientId, oldLeader, newLeader, ioe.getClass().getName());
            this.leaderId = newLeader;
        }
        clientRpc.handleException(oldLeader, ioe, true);
    }
}
Also used : ResourceUnavailableException(org.apache.ratis.protocol.exceptions.ResourceUnavailableException) LeaderNotReadyException(org.apache.ratis.protocol.exceptions.LeaderNotReadyException) RaftPeerId(org.apache.ratis.protocol.RaftPeerId) RaftPeer(org.apache.ratis.protocol.RaftPeer)

Example 2 with ResourceUnavailableException

use of org.apache.ratis.protocol.exceptions.ResourceUnavailableException in project incubator-ratis by apache.

the class RaftServerImpl method appendTransaction.

/**
 * Handle a normal update request from client.
 */
private CompletableFuture<RaftClientReply> appendTransaction(RaftClientRequest request, TransactionContext context, CacheEntry cacheEntry) throws IOException {
    assertLifeCycleState(LifeCycle.States.RUNNING);
    CompletableFuture<RaftClientReply> reply;
    final PendingRequest pending;
    synchronized (this) {
        reply = checkLeaderState(request, cacheEntry, true);
        if (reply != null) {
            return reply;
        }
        // append the message to its local log
        final LeaderStateImpl leaderState = role.getLeaderStateNonNull();
        final PendingRequests.Permit permit = leaderState.tryAcquirePendingRequest(request.getMessage());
        if (permit == null) {
            cacheEntry.failWithException(new ResourceUnavailableException(getMemberId() + ": Failed to acquire a pending write request for " + request));
            return cacheEntry.getReplyFuture();
        }
        try {
            state.appendLog(context);
        } catch (StateMachineException e) {
            // the StateMachineException is thrown by the SM in the preAppend stage.
            // Return the exception in a RaftClientReply.
            RaftClientReply exceptionReply = newExceptionReply(request, e);
            cacheEntry.failWithReply(exceptionReply);
            // leader will step down here
            if (e.leaderShouldStepDown() && getInfo().isLeader()) {
                leaderState.submitStepDownEvent(LeaderState.StepDownReason.STATE_MACHINE_EXCEPTION);
            }
            return CompletableFuture.completedFuture(exceptionReply);
        }
        // put the request into the pending queue
        pending = leaderState.addPendingRequest(permit, request, context);
        if (pending == null) {
            cacheEntry.failWithException(new ResourceUnavailableException(getMemberId() + ": Failed to add a pending write request for " + request));
            return cacheEntry.getReplyFuture();
        }
        leaderState.notifySenders();
    }
    return pending.getFuture();
}
Also used : StateMachineException(org.apache.ratis.protocol.exceptions.StateMachineException) ResourceUnavailableException(org.apache.ratis.protocol.exceptions.ResourceUnavailableException)

Example 3 with ResourceUnavailableException

use of org.apache.ratis.protocol.exceptions.ResourceUnavailableException in project incubator-ratis by apache.

the class TestRetryCacheWithGrpc method testRetryOnResourceUnavailableException.

@Test(timeout = 10000)
public void testRetryOnResourceUnavailableException() throws InterruptedException, IOException {
    RaftProperties properties = new RaftProperties();
    properties.setClass(MiniRaftCluster.STATEMACHINE_CLASS_KEY, SimpleStateMachine4Testing.class, StateMachine.class);
    RaftServerConfigKeys.Write.setElementLimit(properties, 1);
    MiniRaftClusterWithGrpc cluster = getFactory().newCluster(NUM_SERVERS, properties);
    cluster.start();
    final RaftServer.Division leader = RaftTestUtil.waitForLeader(cluster);
    final RaftServer leaderProxy = leader.getRaftServer();
    for (RaftServer.Division follower : cluster.getFollowers()) {
        // block followers to trigger ResourceUnavailableException
        ((SimpleStateMachine4Testing) follower.getStateMachine()).blockWriteStateMachineData();
    }
    AtomicBoolean failure = new AtomicBoolean(false);
    long callId = 1;
    ClientId clientId = ClientId.randomId();
    RaftClientRequest r = null;
    while (!failure.get()) {
        long cid = callId;
        r = cluster.newRaftClientRequest(clientId, leaderProxy.getId(), callId++, new RaftTestUtil.SimpleMessage("message"));
        CompletableFuture<RaftClientReply> f = leaderProxy.submitClientRequestAsync(r);
        f.exceptionally(e -> {
            if (e.getCause() instanceof ResourceUnavailableException) {
                RetryCacheTestUtil.isFailed(RetryCacheTestUtil.get(leader, clientId, cid));
                failure.set(true);
            }
            return null;
        });
    }
    for (RaftServer.Division follower : cluster.getFollowers()) {
        // unblock followers
        ((SimpleStateMachine4Testing) follower.getStateMachine()).unblockWriteStateMachineData();
    }
    while (failure.get()) {
        try {
            // retry until the request failed with ResourceUnavailableException succeeds.
            RaftClientReply reply = leaderProxy.submitClientRequestAsync(r).get();
            if (reply.isSuccess()) {
                failure.set(false);
            }
        } catch (Exception e) {
        // Ignore the exception
        }
    }
    cluster.shutdown();
}
Also used : SimpleStateMachine4Testing(org.apache.ratis.statemachine.SimpleStateMachine4Testing) RaftServer(org.apache.ratis.server.RaftServer) RaftProperties(org.apache.ratis.conf.RaftProperties) ResourceUnavailableException(org.apache.ratis.protocol.exceptions.ResourceUnavailableException) IOException(java.io.IOException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) RaftClientRequest(org.apache.ratis.protocol.RaftClientRequest) RaftClientReply(org.apache.ratis.protocol.RaftClientReply) ResourceUnavailableException(org.apache.ratis.protocol.exceptions.ResourceUnavailableException) ClientId(org.apache.ratis.protocol.ClientId) Test(org.junit.Test)

Aggregations

ResourceUnavailableException (org.apache.ratis.protocol.exceptions.ResourceUnavailableException)3 IOException (java.io.IOException)1 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)1 RaftProperties (org.apache.ratis.conf.RaftProperties)1 ClientId (org.apache.ratis.protocol.ClientId)1 RaftClientReply (org.apache.ratis.protocol.RaftClientReply)1 RaftClientRequest (org.apache.ratis.protocol.RaftClientRequest)1 RaftPeer (org.apache.ratis.protocol.RaftPeer)1 RaftPeerId (org.apache.ratis.protocol.RaftPeerId)1 LeaderNotReadyException (org.apache.ratis.protocol.exceptions.LeaderNotReadyException)1 StateMachineException (org.apache.ratis.protocol.exceptions.StateMachineException)1 RaftServer (org.apache.ratis.server.RaftServer)1 SimpleStateMachine4Testing (org.apache.ratis.statemachine.SimpleStateMachine4Testing)1 Test (org.junit.Test)1