All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.datastax.oss.driver.api.core.retry.RetryPolicy Maven / Gradle / Ivy

The newest version!
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.datastax.oss.driver.api.core.retry;

import com.datastax.oss.driver.api.core.ConsistencyLevel;
import com.datastax.oss.driver.api.core.connection.ClosedConnectionException;
import com.datastax.oss.driver.api.core.connection.HeartbeatException;
import com.datastax.oss.driver.api.core.loadbalancing.LoadBalancingPolicy;
import com.datastax.oss.driver.api.core.servererrors.BootstrappingException;
import com.datastax.oss.driver.api.core.servererrors.CoordinatorException;
import com.datastax.oss.driver.api.core.servererrors.FunctionFailureException;
import com.datastax.oss.driver.api.core.servererrors.OverloadedException;
import com.datastax.oss.driver.api.core.servererrors.ProtocolError;
import com.datastax.oss.driver.api.core.servererrors.QueryValidationException;
import com.datastax.oss.driver.api.core.servererrors.ReadFailureException;
import com.datastax.oss.driver.api.core.servererrors.ReadTimeoutException;
import com.datastax.oss.driver.api.core.servererrors.ServerError;
import com.datastax.oss.driver.api.core.servererrors.TruncateException;
import com.datastax.oss.driver.api.core.servererrors.WriteFailureException;
import com.datastax.oss.driver.api.core.servererrors.WriteType;
import com.datastax.oss.driver.api.core.session.Request;
import edu.umd.cs.findbugs.annotations.NonNull;

/**
 * Defines the behavior to adopt when a request fails.
 *
 * 

For each request, the driver gets a "query plan" (a list of coordinators to try) from the * {@link LoadBalancingPolicy}, and tries each node in sequence. This policy is invoked if the * request to that node fails. * *

The methods of this interface are invoked on I/O threads, therefore implementations should * never block. In particular, don't call {@link Thread#sleep(long)} to retry after a delay: * this would prevent asynchronous processing of other requests, and very negatively impact * throughput. If the application needs to back off and retry later, this should be implemented in * client code, not in this policy. */ public interface RetryPolicy extends AutoCloseable { /** * Whether to retry when the server replied with a {@code READ_TIMEOUT} error; this indicates a * server-side timeout during a read query, i.e. some replicas did not reply to the * coordinator in time. * * @param request the request that timed out. * @param cl the requested consistency level. * @param blockFor the minimum number of replica acknowledgements/responses that were required to * fulfill the operation. * @param received the number of replica that had acknowledged/responded to the operation before * it failed. * @param dataPresent whether the actual data was amongst the received replica responses. See * {@link ReadTimeoutException#wasDataPresent()}. * @param retryCount how many times the retry policy has been invoked already for this request * (not counting the current invocation). * @deprecated As of version 4.10, use {@link #onReadTimeoutVerdict(Request, ConsistencyLevel, * int, int, boolean, int)} instead. */ @Deprecated RetryDecision onReadTimeout( @NonNull Request request, @NonNull ConsistencyLevel cl, int blockFor, int received, boolean dataPresent, int retryCount); /** * Whether to retry when the server replied with a {@code READ_TIMEOUT} error; this indicates a * server-side timeout during a read query, i.e. some replicas did not reply to the * coordinator in time. * * @param request the request that timed out. * @param cl the requested consistency level. * @param blockFor the minimum number of replica acknowledgements/responses that were required to * fulfill the operation. * @param received the number of replica that had acknowledged/responded to the operation before * it failed. * @param dataPresent whether the actual data was amongst the received replica responses. See * {@link ReadTimeoutException#wasDataPresent()}. * @param retryCount how many times the retry policy has been invoked already for this request * (not counting the current invocation). */ default RetryVerdict onReadTimeoutVerdict( @NonNull Request request, @NonNull ConsistencyLevel cl, int blockFor, int received, boolean dataPresent, int retryCount) { RetryDecision decision = onReadTimeout(request, cl, blockFor, received, dataPresent, retryCount); return () -> decision; } /** * Whether to retry when the server replied with a {@code WRITE_TIMEOUT} error; this indicates a * server-side timeout during a write query, i.e. some replicas did not reply to the * coordinator in time. * *

Note that this method will only be invoked for {@link Request#isIdempotent()} idempotent} * requests: when a write times out, it is impossible to determine with 100% certainty whether the * mutation was applied or not, so the write is never safe to retry; the driver will rethrow the * error directly, without invoking the retry policy. * * @param request the request that timed out. * @param cl the requested consistency level. * @param writeType the type of the write for which the timeout was raised. * @param blockFor the minimum number of replica acknowledgements/responses that were required to * fulfill the operation. * @param received the number of replica that had acknowledged/responded to the operation before * it failed. * @param retryCount how many times the retry policy has been invoked already for this request * (not counting the current invocation). * @deprecated As of version 4.10, use {@link #onWriteTimeoutVerdict(Request, ConsistencyLevel, * WriteType, int, int, int)} instead. */ @Deprecated RetryDecision onWriteTimeout( @NonNull Request request, @NonNull ConsistencyLevel cl, @NonNull WriteType writeType, int blockFor, int received, int retryCount); /** * Whether to retry when the server replied with a {@code WRITE_TIMEOUT} error; this indicates a * server-side timeout during a write query, i.e. some replicas did not reply to the * coordinator in time. * *

Note that this method will only be invoked for {@link Request#isIdempotent()} idempotent} * requests: when a write times out, it is impossible to determine with 100% certainty whether the * mutation was applied or not, so the write is never safe to retry; the driver will rethrow the * error directly, without invoking the retry policy. * * @param request the request that timed out. * @param cl the requested consistency level. * @param writeType the type of the write for which the timeout was raised. * @param blockFor the minimum number of replica acknowledgements/responses that were required to * fulfill the operation. * @param received the number of replica that had acknowledged/responded to the operation before * it failed. * @param retryCount how many times the retry policy has been invoked already for this request * (not counting the current invocation). */ default RetryVerdict onWriteTimeoutVerdict( @NonNull Request request, @NonNull ConsistencyLevel cl, @NonNull WriteType writeType, int blockFor, int received, int retryCount) { RetryDecision decision = onWriteTimeout(request, cl, writeType, blockFor, received, retryCount); return () -> decision; } /** * Whether to retry when the server replied with an {@code UNAVAILABLE} error; this indicates that * the coordinator determined that there were not enough replicas alive to perform a query with * the requested consistency level. * * @param request the request that timed out. * @param cl the requested consistency level. * @param required the number of replica acknowledgements/responses required to perform the * operation (with its required consistency level). * @param alive the number of replicas that were known to be alive by the coordinator node when it * tried to execute the operation. * @param retryCount how many times the retry policy has been invoked already for this request * (not counting the current invocation). * @deprecated As of version 4.10, use {@link #onUnavailableVerdict(Request, ConsistencyLevel, * int, int, int)} instead. */ @Deprecated RetryDecision onUnavailable( @NonNull Request request, @NonNull ConsistencyLevel cl, int required, int alive, int retryCount); /** * Whether to retry when the server replied with an {@code UNAVAILABLE} error; this indicates that * the coordinator determined that there were not enough replicas alive to perform a query with * the requested consistency level. * * @param request the request that timed out. * @param cl the requested consistency level. * @param required the number of replica acknowledgements/responses required to perform the * operation (with its required consistency level). * @param alive the number of replicas that were known to be alive by the coordinator node when it * tried to execute the operation. * @param retryCount how many times the retry policy has been invoked already for this request * (not counting the current invocation). */ default RetryVerdict onUnavailableVerdict( @NonNull Request request, @NonNull ConsistencyLevel cl, int required, int alive, int retryCount) { RetryDecision decision = onUnavailable(request, cl, required, alive, retryCount); return () -> decision; } /** * Whether to retry when a request was aborted before we could get a response from the server. * *

This can happen in two cases: if the connection was closed due to an external event (this * will manifest as a {@link ClosedConnectionException}, or {@link HeartbeatException} for a * heartbeat failure); or if there was an unexpected error while decoding the response (this can * only be a driver bug). * *

Note that this method will only be invoked for {@linkplain Request#isIdempotent() * idempotent} requests: when execution was aborted before getting a response, it is impossible to * determine with 100% certainty whether a mutation was applied or not, so a write is never safe * to retry; the driver will rethrow the error directly, without invoking the retry policy. * * @param request the request that was aborted. * @param error the error. * @param retryCount how many times the retry policy has been invoked already for this request * (not counting the current invocation). * @deprecated As of version 4.10, use {@link #onRequestAbortedVerdict(Request, Throwable, int)} * instead. */ @Deprecated RetryDecision onRequestAborted( @NonNull Request request, @NonNull Throwable error, int retryCount); /** * Whether to retry when a request was aborted before we could get a response from the server. * *

This can happen in two cases: if the connection was closed due to an external event (this * will manifest as a {@link ClosedConnectionException}, or {@link HeartbeatException} for a * heartbeat failure); or if there was an unexpected error while decoding the response (this can * only be a driver bug). * *

Note that this method will only be invoked for {@linkplain Request#isIdempotent() * idempotent} requests: when execution was aborted before getting a response, it is impossible to * determine with 100% certainty whether a mutation was applied or not, so a write is never safe * to retry; the driver will rethrow the error directly, without invoking the retry policy. * * @param request the request that was aborted. * @param error the error. * @param retryCount how many times the retry policy has been invoked already for this request * (not counting the current invocation). */ default RetryVerdict onRequestAbortedVerdict( @NonNull Request request, @NonNull Throwable error, int retryCount) { RetryDecision decision = onRequestAborted(request, error, retryCount); return () -> decision; } /** * Whether to retry when the server replied with a recoverable error (other than {@code * READ_TIMEOUT}, {@code WRITE_TIMEOUT} or {@code UNAVAILABLE}). * *

This can happen for the following errors: {@link OverloadedException}, {@link ServerError}, * {@link TruncateException}, {@link ReadFailureException}, {@link WriteFailureException}. * *

The following errors are handled internally by the driver, and therefore will never * be encountered in this method: * *

    *
  • {@link BootstrappingException}: always retried on the next node; *
  • {@link QueryValidationException} (and its subclasses), {@link FunctionFailureException} * and {@link ProtocolError}: always rethrown. *
* *

Note that this method will only be invoked for {@link Request#isIdempotent()} idempotent} * requests: when execution was aborted before getting a response, it is impossible to determine * with 100% certainty whether a mutation was applied or not, so a write is never safe to retry; * the driver will rethrow the error directly, without invoking the retry policy. * * @param request the request that failed. * @param error the error. * @param retryCount how many times the retry policy has been invoked already for this request * (not counting the current invocation). * @deprecated As of version 4.10, use {@link #onErrorResponseVerdict(Request, * CoordinatorException, int)} instead. */ @Deprecated RetryDecision onErrorResponse( @NonNull Request request, @NonNull CoordinatorException error, int retryCount); /** * Whether to retry when the server replied with a recoverable error (other than {@code * READ_TIMEOUT}, {@code WRITE_TIMEOUT} or {@code UNAVAILABLE}). * *

This can happen for the following errors: {@link OverloadedException}, {@link ServerError}, * {@link TruncateException}, {@link ReadFailureException}, {@link WriteFailureException}. * *

The following errors are handled internally by the driver, and therefore will never * be encountered in this method: * *

    *
  • {@link BootstrappingException}: always retried on the next node; *
  • {@link QueryValidationException} (and its subclasses), {@link FunctionFailureException} * and {@link ProtocolError}: always rethrown. *
* *

Note that this method will only be invoked for {@link Request#isIdempotent()} idempotent} * requests: when execution was aborted before getting a response, it is impossible to determine * with 100% certainty whether a mutation was applied or not, so a write is never safe to retry; * the driver will rethrow the error directly, without invoking the retry policy. * * @param request the request that failed. * @param error the error. * @param retryCount how many times the retry policy has been invoked already for this request * (not counting the current invocation). */ default RetryVerdict onErrorResponseVerdict( @NonNull Request request, @NonNull CoordinatorException error, int retryCount) { RetryDecision decision = onErrorResponse(request, error, retryCount); return () -> decision; } /** Called when the cluster that this policy is associated with closes. */ @Override void close(); }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy