This is an automated email from the ASF dual-hosted git repository.

joaoreis pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/cassandra-gocql-driver.git


The following commit(s) were added to refs/heads/trunk by this push:
     new c34640d  Don't return error to caller with RetryType Ignore
c34640d is described below

commit c34640dc8ca1047334da1d7b5689725c2be21061
Author: Rikkuru <5867722+rikk...@users.noreply.github.com>
AuthorDate: Thu Nov 21 20:27:24 2024 +0300

    Don't return error to caller with RetryType Ignore
    
    RetryType Ignore is documented and should work according to the 
documentation. Error is not returned to caller on ignore but can be seen in 
ObservedQuery. RetryType should be checked even if RetryPolicy.Attempt returns 
false, otherwise Ignore will not work on last attempt.
    
    Patch by Rikkuru; reviewed by João Reis, Jackson Fleming for CASSGO-28
---
 CHANGELOG.md      |  1 +
 query_executor.go | 28 ++++++++++++++++-------
 session_test.go   | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 88 insertions(+), 8 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6c00549..a83e6f8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -17,6 +17,7 @@ and this project adheres to [Semantic 
Versioning](https://semver.org/spec/v2.0.0
 ### Fixed
 
 - Retry policy now takes into account query idempotency (CASSGO-27)
+- Don't return error to caller with RetryType Ignore (CASSGO-28)
 
 ## [1.7.0] - 2024-09-23
 
diff --git a/query_executor.go b/query_executor.go
index 0368736..d6be02e 100644
--- a/query_executor.go
+++ b/query_executor.go
@@ -165,27 +165,39 @@ func (q *queryExecutor) do(ctx context.Context, qry 
ExecutableQuery, hostIter Ne
                }
 
                // Exit if the query was successful
-               // or no retry policy defined or retry attempts were reached
-               if iter.err == nil || !qry.IsIdempotent() || rt == nil || 
!rt.Attempt(qry) {
+               // or query is not idempotent or no retry policy defined
+               if iter.err == nil || !qry.IsIdempotent() || rt == nil {
                        return iter
                }
-               lastErr = iter.err
+
+               attemptsReached := !rt.Attempt(qry)
+               retryType := rt.GetRetryType(iter.err)
+
+               var stopRetries bool
 
                // If query is unsuccessful, check the error with RetryPolicy 
to retry
-               switch rt.GetRetryType(iter.err) {
+               switch retryType {
                case Retry:
                        // retry on the same host
-                       continue
-               case Rethrow, Ignore:
-                       return iter
                case RetryNextHost:
                        // retry on the next host
                        selectedHost = hostIter()
-                       continue
+               case Ignore:
+                       iter.err = nil
+                       stopRetries = true
+               case Rethrow:
+                       stopRetries = true
                default:
                        // Undefined? Return nil and error, this will panic in 
the requester
                        return &Iter{err: ErrUnknownRetryType}
                }
+
+               if stopRetries || attemptsReached {
+                       return iter
+               }
+
+               lastErr = iter.err
+               continue
        }
 
        if lastErr != nil {
diff --git a/session_test.go b/session_test.go
index 0319a8a..c7bafbb 100644
--- a/session_test.go
+++ b/session_test.go
@@ -347,3 +347,70 @@ func TestIsUseStatement(t *testing.T) {
                }
        }
 }
+
+type simpleTestRetryPolycy struct {
+       RetryType  RetryType
+       NumRetries int
+}
+
+func (p *simpleTestRetryPolycy) Attempt(q RetryableQuery) bool {
+       return q.Attempts() <= p.NumRetries
+}
+
+func (p *simpleTestRetryPolycy) GetRetryType(error) RetryType {
+       return p.RetryType
+}
+
+// TestRetryType_IgnoreRethrow verify that with Ignore/Rethrow retry types:
+// - retries stopped
+// - return error is nil on Ignore
+// - return error is not nil on Rethrow
+// - observed error is not nil
+func TestRetryType_IgnoreRethrow(t *testing.T) {
+       session := createSession(t)
+       defer session.Close()
+
+       var observedErr error
+       var observedAttempts int
+
+       resetObserved := func() {
+               observedErr = nil
+               observedAttempts = 0
+       }
+
+       observer := funcQueryObserver(func(ctx context.Context, o 
ObservedQuery) {
+               observedErr = o.Err
+               observedAttempts++
+       })
+
+       for _, caseParams := range []struct {
+               retries   int
+               retryType RetryType
+       }{
+               {0, Ignore},  // check that error ignored even on last attempt
+               {1, Ignore},  // check thet ignore stops retries
+               {1, Rethrow}, // check thet rethrow stops retries
+       } {
+               retryPolicy := &simpleTestRetryPolycy{RetryType: 
caseParams.retryType, NumRetries: caseParams.retries}
+
+               err := session.Query("INSERT INTO 
gocql_test.invalid_table(value) 
VALUES(1)").Idempotent(true).RetryPolicy(retryPolicy).Observer(observer).Exec()
+
+               if err != nil && caseParams.retryType == Ignore {
+                       t.Fatalf("[%v] Expected no error, got: %s", 
caseParams.retryType, err)
+               }
+
+               if err == nil && caseParams.retryType == Rethrow {
+                       t.Fatalf("[%v] Expected unconfigured table error, got: 
nil", caseParams.retryType)
+               }
+
+               if observedErr == nil {
+                       t.Fatal("Expected unconfigured table error in Obserer, 
got: nil")
+               }
+
+               if observedAttempts > 1 {
+                       t.Fatalf("Expected one attempt, got: %d", 
observedAttempts)
+               }
+
+               resetObserved()
+       }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@cassandra.apache.org
For additional commands, e-mail: commits-h...@cassandra.apache.org

Reply via email to