Beispiel #1
0
        /// <summary>
        ///  Defines whether to retry and at which consistency level on a write timeout.
        ///  <p> This method triggers a maximum of one retry. If <c>writeType ==
        ///  WriteType.BATCH_LOG</c>, the write is retried with the initial consistency
        ///  level. If <c>writeType == WriteType.UNLOGGED_BATCH</c> and at least one
        ///  replica acknowleged, the write is retried with a lower consistency level
        ///  (with unlogged batch, a write timeout can <b>always</b> mean that part of the
        ///  batch haven't been persisted at' all, even if <c>receivedAcks > 0</c>).
        ///  For other <c>writeType</c>, if we know the write has been persisted on
        ///  at least one replica, we ignore the exception. Otherwise, an exception is
        ///  thrown.</p>
        /// </summary>
        /// <param name="query"> the original query that timeouted. </param>
        /// <param name="cl"> the original consistency level of the write that timeouted.
        ///  </param>
        /// <param name="writeType"> the type of the write that timeouted. </param>
        /// <param name="requiredAcks"> the number of acknowledgments that were required
        ///  to achieve the requested consistency level. </param>
        /// <param name="receivedAcks"> the number of acknowledgments that had been
        ///  received by the time the timeout exception was raised. </param>
        /// <param name="nbRetry"> the number of retry already performed for this
        ///  operation. </param>
        ///
        /// <returns>a RetryDecision as defined above.</returns>
        public RetryDecision OnWriteTimeout(IStatement query, ConsistencyLevel cl, string writeType, int requiredAcks, int receivedAcks, int nbRetry)
        {
            if (nbRetry != 0)
            {
                return(RetryDecision.Rethrow());
            }

            switch (writeType)
            {
            case "SIMPLE":
            case "BATCH":
                // Since we provide atomicity there is no point in retrying
                return(RetryDecision.Ignore());

            case "COUNTER":
                // We should not retry counters, period!
                return(RetryDecision.Ignore());

            case "UNLOGGED_BATCH":
                // Since only part of the batch could have been persisted,
                // retry with whatever consistency should allow to persist all
                return(MaxLikelyToWorkCl(receivedAcks));

            case "BATCH_LOG":
                return(RetryDecision.Retry(cl));
            }
            return(RetryDecision.Rethrow());
        }
        /// <summary>
        /// Gets the retry decision based on the exception from Cassandra
        /// </summary>
        public RetryDecision GetRetryDecision(Exception ex)
        {
            RetryDecision decision = RetryDecision.Rethrow();

            if (ex is SocketException)
            {
                decision = RetryDecision.Retry(null);
            }
            else if (ex is OverloadedException || ex is IsBootstrappingException || ex is TruncateException)
            {
                decision = RetryDecision.Retry(null);
            }
            else if (ex is ReadTimeoutException)
            {
                var e = ex as ReadTimeoutException;
                decision = _retryPolicy.OnReadTimeout(_statement, e.ConsistencyLevel, e.RequiredAcknowledgements, e.ReceivedAcknowledgements, e.WasDataRetrieved, _retryCount);
            }
            else if (ex is WriteTimeoutException)
            {
                var e = ex as WriteTimeoutException;
                decision = _retryPolicy.OnWriteTimeout(_statement, e.ConsistencyLevel, e.WriteType, e.RequiredAcknowledgements, e.ReceivedAcknowledgements, _retryCount);
            }
            else if (ex is UnavailableException)
            {
                var e = ex as UnavailableException;
                decision = _retryPolicy.OnUnavailable(_statement, e.Consistency, e.RequiredReplicas, e.AliveReplicas, _retryCount);
            }
            return(decision);
        }
 /// <summary>
 /// The default implementation triggers a retry on the next host in the query plan with the same consistency level,
 /// regardless of the statement's idempotence, for historical reasons.
 /// </summary>
 public RetryDecision OnRequestError(IStatement statement, Configuration config, Exception ex, int nbRetry)
 {
     if (ex is OperationTimedOutException && !config.QueryOptions.RetryOnTimeout)
     {
         return(RetryDecision.Rethrow());
     }
     return(RetryDecision.Retry(null, false));
 }
        /// <summary>
        ///  Defines whether to retry and at which consistency level on a write timeout.
        ///  <p> This method triggers a maximum of one retry, and only in the case of a
        ///  <c>WriteType.BATCH_LOG</c> write. The reasoning for the retry in that
        ///  case is that write to the distributed batch log is tried by the coordinator
        ///  of the write against a small subset of all the node alive in the local
        ///  datacenter. Hence, a timeout usually means that none of the nodes in that
        ///  subset were alive but the coordinator hasn't' detected them as dead. By the
        ///  time we get the timeout the dead nodes will likely have been detected as dead
        ///  and the retry has thus a high change of success.</p>
        /// </summary>
        /// <param name="query"> the original query that timeouted. </param>
        /// <param name="cl"> the original consistency level of the write that timeouted.
        ///  </param>
        /// <param name="writeType"> the type of the write that timeouted. </param>
        /// <param name="requiredAcks"> the number of acknowledgments that were required
        ///  to achieve the requested consistency level. </param>
        /// <param name="receivedAcks"> the number of acknowledgments that had been
        ///  received by the time the timeout exception was raised. </param>
        /// <param name="nbRetry"> the number of retry already performed for this
        ///  operation. </param>
        ///
        /// <returns><c>RetryDecision.retry(cl)</c> if no retry attempt has yet
        ///  been tried and <c>writeType == WriteType.BATCH_LOG</c>,
        ///  <c>RetryDecision.rethrow()</c> otherwise.</returns>
        public RetryDecision OnWriteTimeout(IStatement query, ConsistencyLevel cl, string writeType, int requiredAcks, int receivedAcks,
                                            int nbRetry)
        {
            if (nbRetry != 0)
            {
                return(RetryDecision.Rethrow());
            }

            // If the batch log write failed, retry the operation as this might just be we were unlucky at picking candidtes
            return(writeType == "BATCH_LOG" ? RetryDecision.Retry(cl) : RetryDecision.Rethrow());
        }
Beispiel #5
0
 /// <inheritdoc />
 public RetryDecision OnRequestError(IStatement stmt, Configuration config, Exception ex, int nbRetry)
 {
     if (stmt != null && stmt.IsIdempotent == true)
     {
         if (_extendedChildPolicy != null)
         {
             return(_extendedChildPolicy.OnRequestError(stmt, config, ex, nbRetry));
         }
         return(RetryDecision.Retry(null, false));
     }
     return(RetryDecision.Rethrow());
 }
        /// <summary>
        ///  Defines whether to retry and at which consistency level on a read timeout.
        ///  <p> This method triggers a maximum of one retry, and only if enough replica
        ///  had responded to the read request but data was not retrieved amongst those.
        ///  Indeed, that case usually means that enough replica are alive to satisfy the
        ///  consistency but the coordinator picked a dead one for data retrieval, not
        ///  having detected that replica as dead yet. The reasoning for retrying then is
        ///  that by the time we get the timeout the dead replica will likely have been
        ///  detected as dead and the retry has a high change of success.</p>
        /// </summary>
        /// <param name="query"> the original query that timed out. </param>
        /// <param name="cl"> the original consistency level of the read that timed out.
        ///  </param>
        /// <param name="requiredResponses"> the number of responses that were required
        ///  to achieve the requested consistency level. </param>
        /// <param name="receivedResponses"> the number of responses that had been
        ///  received by the time the timeout exception was raised. </param>
        /// <param name="dataRetrieved"> whether actual data (by opposition to data
        ///  checksum) was present in the received responses. </param>
        /// <param name="nbRetry"> the number of retry already performed for this
        ///  operation. </param>
        ///
        /// <returns><c>RetryDecision.Retry(cl)</c> if no retry attempt has yet
        ///  been tried and <c>receivedResponses >= requiredResponses &amp;&amp;
        ///  !dataRetrieved</c>, <c>RetryDecision.Rethrow()</c>
        ///  otherwise.</returns>
        public RetryDecision OnReadTimeout(IStatement query, ConsistencyLevel cl, int requiredResponses, int receivedResponses,
                                           bool dataRetrieved, int nbRetry)
        {
            if (nbRetry != 0)
            {
                return(RetryDecision.Rethrow());
            }

            return(receivedResponses >= requiredResponses && !dataRetrieved
                       ? RetryDecision.Retry(cl)
                       : RetryDecision.Rethrow());
        }
Beispiel #7
0
 private static RetryDecision MaxLikelyToWorkCl(int knownOk)
 {
     if (knownOk >= 3)
     {
         return(RetryDecision.Retry(ConsistencyLevel.Three));
     }
     if (knownOk >= 2)
     {
         return(RetryDecision.Retry(ConsistencyLevel.Two));
     }
     if (knownOk >= 1)
     {
         return(RetryDecision.Retry(ConsistencyLevel.One));
     }
     return(RetryDecision.Rethrow());
 }
Beispiel #8
0
        /// <summary>
        ///  Defines whether to retry and at which consistency level on a read timeout.
        ///  <p> This method triggers a maximum of one retry. If less replica responsed
        ///  than required by the consistency level (but at least one replica did
        ///  respond), the operation is retried at a lower consistency level. If enough
        ///  replica responded but data was not retrieve, the operation is retried with
        ///  the initial consistency level. Otherwise, an exception is thrown.</p>
        /// </summary>
        /// <param name="query"> the original query that timeouted. </param>
        /// <param name="cl"> the original consistency level of the read that timeouted.
        ///  </param>
        /// <param name="requiredResponses"> the number of responses that were required
        ///  to achieve the requested consistency level. </param>
        /// <param name="receivedResponses"> the number of responses that had been
        ///  received by the time the timeout exception was raised. </param>
        /// <param name="dataRetrieved"> whether actual data (by opposition to data
        ///  checksum) was present in the received responses. </param>
        /// <param name="nbRetry"> the number of retry already performed for this
        ///  operation. </param>
        ///
        /// <returns>a RetryDecision as defined above.</returns>
        public RetryDecision OnReadTimeout(IStatement query, ConsistencyLevel cl, int requiredResponses, int receivedResponses, bool dataRetrieved,
                                           int nbRetry)
        {
            if (nbRetry != 0)
            {
                return(RetryDecision.Rethrow());
            }

            if (receivedResponses < requiredResponses)
            {
                // Tries the biggest CL that is expected to work
                return(MaxLikelyToWorkCl(receivedResponses));
            }

            return(!dataRetrieved?RetryDecision.Retry(cl) : RetryDecision.Rethrow());
        }
Beispiel #9
0
        static RetryDecision GetRetryDecision(Query query, QueryValidationException exc, IRetryPolicy policy, int queryRetries)
        {
            if (exc is OverloadedException)
            {
                return(RetryDecision.Retry(null));
            }
            else if (exc is IsBootstrappingException)
            {
                return(RetryDecision.Retry(null));
            }
            else if (exc is TruncateException)
            {
                return(RetryDecision.Retry(null));
            }

            else if (exc is ReadTimeoutException)
            {
                var e = exc as ReadTimeoutException;
                return(policy.OnReadTimeout(query, e.ConsistencyLevel, e.RequiredAcknowledgements, e.ReceivedAcknowledgements, e.WasDataRetrieved, queryRetries));
            }
            else if (exc is WriteTimeoutException)
            {
                var e = exc as WriteTimeoutException;
                return(policy.OnWriteTimeout(query, e.ConsistencyLevel, e.WriteType, e.RequiredAcknowledgements, e.ReceivedAcknowledgements, queryRetries));
            }
            else if (exc is UnavailableException)
            {
                var e = exc as UnavailableException;
                return(policy.OnUnavailable(query, e.Consistency, e.RequiredReplicas, e.AliveReplicas, queryRetries));
            }

            else if (exc is AlreadyExistsException)
            {
                return(RetryDecision.Rethrow());
            }
            else if (exc is InvalidConfigurationInQueryException)
            {
                return(RetryDecision.Rethrow());
            }
            else if (exc is PreparedQueryNotFoundException)
            {
                return(RetryDecision.Rethrow());
            }
            else if (exc is ProtocolErrorException)
            {
                return(RetryDecision.Rethrow());
            }
            else if (exc is InvalidQueryException)
            {
                return(RetryDecision.Rethrow());
            }
            else if (exc is UnauthorizedException)
            {
                return(RetryDecision.Rethrow());
            }
            else if (exc is SyntaxError)
            {
                return(RetryDecision.Rethrow());
            }

            else if (exc is ServerErrorException)
            {
                return(null);
            }
            else
            {
                return(null);
            }
        }