use of org.apache.ratis.client.retry.ClientRetryEvent in project incubator-ratis by apache.
the class UnorderedAsync method sendRequestWithRetry.
static void sendRequestWithRetry(PendingClientRequest pending, RaftClientImpl client) {
final CompletableFuture<RaftClientReply> f = pending.getReplyFuture();
if (f.isDone()) {
return;
}
final RaftClientRequest request = pending.newRequest();
final int attemptCount = pending.getAttemptCount();
final ClientId clientId = client.getId();
LOG.debug("{}: attempt #{} send~ {}", clientId, attemptCount, request);
client.getClientRpc().sendRequestAsyncUnordered(request).whenCompleteAsync((reply, e) -> {
try {
LOG.debug("{}: attempt #{} receive~ {}", clientId, attemptCount, reply);
final RaftException replyException = reply != null ? reply.getException() : null;
reply = client.handleLeaderException(request, reply);
if (reply != null) {
client.handleReply(request, reply);
f.complete(reply);
return;
}
final Throwable cause = replyException != null ? replyException : e;
pending.incrementExceptionCount(cause);
final ClientRetryEvent event = new ClientRetryEvent(request, cause, pending);
RetryPolicy retryPolicy = client.getRetryPolicy();
final RetryPolicy.Action action = retryPolicy.handleAttemptFailure(event);
TimeDuration sleepTime = client.getEffectiveSleepTime(cause, action.getSleepTime());
if (!action.shouldRetry()) {
f.completeExceptionally(client.noMoreRetries(event));
return;
}
if (e != null) {
if (LOG.isTraceEnabled()) {
LOG.trace(clientId + ": attempt #" + attemptCount + " failed~ " + request, e);
} else {
LOG.debug("{}: attempt #{} failed {} with {}", clientId, attemptCount, request, e);
}
e = JavaUtils.unwrapCompletionException(e);
if (e instanceof IOException) {
if (e instanceof NotLeaderException) {
client.handleNotLeaderException(request, (NotLeaderException) e, null);
} else if (e instanceof GroupMismatchException) {
f.completeExceptionally(e);
return;
} else {
client.handleIOException(request, (IOException) e);
}
} else {
if (!client.getClientRpc().handleException(request.getServerId(), e, false)) {
f.completeExceptionally(e);
return;
}
}
}
LOG.debug("schedule retry for attempt #{}, policy={}, request={}", attemptCount, retryPolicy, request);
client.getScheduler().onTimeout(sleepTime, () -> sendRequestWithRetry(pending, client), LOG, () -> clientId + ": Failed~ to retry " + request);
} catch (Exception ex) {
LOG.error(clientId + ": Failed " + request, ex);
f.completeExceptionally(ex);
}
});
}
use of org.apache.ratis.client.retry.ClientRetryEvent in project incubator-ratis by apache.
the class TestRetryPolicy method testRequestTypeDependentRetry.
@Test
public void testRequestTypeDependentRetry() {
final RequestTypeDependentRetryPolicy.Builder b = RequestTypeDependentRetryPolicy.newBuilder();
final int n = 4;
final TimeDuration writeSleep = HUNDRED_MILLIS;
final RetryPolicies.RetryLimited writePolicy = RetryPolicies.retryUpToMaximumCountWithFixedSleep(n, writeSleep);
b.setRetryPolicy(RaftClientRequestProto.TypeCase.WRITE, writePolicy);
b.setRetryPolicy(RaftClientRequestProto.TypeCase.WATCH, RetryPolicies.noRetry());
final RetryPolicy policy = b.build();
LOG.info("policy = {}", policy);
final RaftClientRequest staleReadRequest = newRaftClientRequest(RaftClientRequest.staleReadRequestType(1));
final RaftClientRequest readRequest = newRaftClientRequest(RaftClientRequest.readRequestType());
final RaftClientRequest writeRequest = newRaftClientRequest(RaftClientRequest.writeRequestType());
final RaftClientRequest watchRequest = newRaftClientRequest(RaftClientRequest.watchRequestType(1, ReplicationLevel.MAJORITY));
for (int i = 1; i < 2 * n; i++) {
{
// write
final ClientRetryEvent event = new ClientRetryEvent(i, writeRequest, null);
final RetryPolicy.Action action = policy.handleAttemptFailure(event);
final boolean expected = i < n;
Assert.assertEquals(expected, action.shouldRetry());
if (expected) {
Assert.assertEquals(writeSleep, action.getSleepTime());
} else {
Assert.assertEquals(0L, action.getSleepTime().getDuration());
}
}
{
// read and stale read are using default
final ClientRetryEvent event = new ClientRetryEvent(i, readRequest, null);
final RetryPolicy.Action action = policy.handleAttemptFailure(event);
Assert.assertTrue(action.shouldRetry());
Assert.assertEquals(0L, action.getSleepTime().getDuration());
}
{
final ClientRetryEvent event = new ClientRetryEvent(i, staleReadRequest, null);
final RetryPolicy.Action action = policy.handleAttemptFailure(event);
Assert.assertTrue(action.shouldRetry());
Assert.assertEquals(0L, action.getSleepTime().getDuration());
}
{
// watch has no retry
final ClientRetryEvent event = new ClientRetryEvent(i, watchRequest, null);
final RetryPolicy.Action action = policy.handleAttemptFailure(event);
Assert.assertFalse(action.shouldRetry());
Assert.assertEquals(0L, action.getSleepTime().getDuration());
}
}
}
use of org.apache.ratis.client.retry.ClientRetryEvent in project incubator-ratis by apache.
the class TestRetryPolicy method testRequestTypeDependentRetryWithTimeout.
@Test
public void testRequestTypeDependentRetryWithTimeout() throws InterruptedException {
final RequestTypeDependentRetryPolicy.Builder b = RequestTypeDependentRetryPolicy.newBuilder();
b.setRetryPolicy(RaftClientRequestProto.TypeCase.WRITE, RetryPolicies.retryForeverNoSleep());
b.setRetryPolicy(RaftClientRequestProto.TypeCase.WATCH, RetryPolicies.retryForeverNoSleep());
TimeDuration timeout = TimeDuration.valueOf(10, TimeUnit.MILLISECONDS);
final RetryPolicy policy = b.setTimeout(RaftClientRequestProto.TypeCase.WRITE, timeout).setTimeout(RaftClientRequestProto.TypeCase.WATCH, timeout).build();
LOG.info("policy = {}", policy);
final RaftClientRequest writeRequest = newRaftClientRequest(RaftClientRequest.writeRequestType());
final RaftClientRequest watchRequest = newRaftClientRequest(RaftClientRequest.watchRequestType(1, ReplicationLevel.MAJORITY));
RaftClientRequest[] requests = new RaftClientRequest[] { writeRequest, watchRequest };
RaftClientImpl.PendingClientRequest pending = new RaftClientImpl.PendingClientRequest() {
@Override
public RaftClientRequest newRequestImpl() {
return null;
}
};
for (RaftClientRequest request : requests) {
final ClientRetryEvent event = new ClientRetryEvent(request, new Exception(), pending);
final RetryPolicy.Action action = policy.handleAttemptFailure(event);
Assert.assertTrue(action.shouldRetry());
Assert.assertEquals(0L, action.getSleepTime().getDuration());
}
Thread.sleep(timeout.toLong(TimeUnit.MILLISECONDS) * 10);
for (RaftClientRequest request : requests) {
final ClientRetryEvent event = new ClientRetryEvent(request, new Exception(), pending);
final RetryPolicy.Action action = policy.handleAttemptFailure(event);
Assert.assertFalse(action.shouldRetry());
}
}
Aggregations