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

btellier pushed a commit to branch postgresql
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit 9081a2f5a0aedc0bc921a88d340200e36902a381
Author: Quan Tran <hqt...@linagora.com>
AuthorDate: Tue Dec 5 12:25:00 2023 +0700

    JAMES-2586 PostgresExecutor: Retry only upon PreparedStatement conflict 
exception
    
    io.r2dbc.postgresql.ExceptionFactory$PostgresqlBadGrammarException: [42P05] 
prepared statement "S_0" already exists
    
    Should not retry upon other fatal exception e.g. database failure, invalid 
authorization...
---
 .../backends/postgres/utils/PostgresExecutor.java      | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git 
a/backends-common/postgres/src/main/java/org/apache/james/backends/postgres/utils/PostgresExecutor.java
 
b/backends-common/postgres/src/main/java/org/apache/james/backends/postgres/utils/PostgresExecutor.java
index b8c39ae88f..b530405f09 100644
--- 
a/backends-common/postgres/src/main/java/org/apache/james/backends/postgres/utils/PostgresExecutor.java
+++ 
b/backends-common/postgres/src/main/java/org/apache/james/backends/postgres/utils/PostgresExecutor.java
@@ -22,6 +22,7 @@ package org.apache.james.backends.postgres.utils;
 import java.time.Duration;
 import java.util.Optional;
 import java.util.function.Function;
+import java.util.function.Predicate;
 
 import javax.inject.Inject;
 
@@ -37,6 +38,7 @@ import org.jooq.impl.DSL;
 import com.google.common.annotations.VisibleForTesting;
 
 import io.r2dbc.spi.Connection;
+import io.r2dbc.spi.R2dbcBadGrammarException;
 import reactor.core.publisher.Flux;
 import reactor.core.publisher.Mono;
 import reactor.util.retry.Retry;
@@ -82,26 +84,30 @@ public class PostgresExecutor {
     public Mono<Void> executeVoid(Function<DSLContext, Mono<?>> queryFunction) 
{
         return dslContext()
             .flatMap(queryFunction)
-            .retryWhen(Retry.backoff(MAX_RETRY_ATTEMPTS, MIN_BACKOFF))
+            .retryWhen(Retry.backoff(MAX_RETRY_ATTEMPTS, MIN_BACKOFF)
+                .filter(preparedStatementConflictException()))
             .then();
     }
 
     public Flux<Record> executeRows(Function<DSLContext, Flux<Record>> 
queryFunction) {
         return dslContext()
             .flatMapMany(queryFunction)
-            .retryWhen(Retry.backoff(MAX_RETRY_ATTEMPTS, MIN_BACKOFF));
+            .retryWhen(Retry.backoff(MAX_RETRY_ATTEMPTS, MIN_BACKOFF)
+                .filter(preparedStatementConflictException()));
     }
 
     public Mono<Record> executeRow(Function<DSLContext, Mono<Record>> 
queryFunction) {
         return dslContext()
             .flatMap(queryFunction)
-            .retryWhen(Retry.backoff(MAX_RETRY_ATTEMPTS, MIN_BACKOFF));
+            .retryWhen(Retry.backoff(MAX_RETRY_ATTEMPTS, MIN_BACKOFF)
+                .filter(preparedStatementConflictException()));
     }
 
     public Mono<Integer> executeCount(Function<DSLContext, 
Mono<Record1<Integer>>> queryFunction) {
         return dslContext()
             .flatMap(queryFunction)
-            .retryWhen(Retry.backoff(MAX_RETRY_ATTEMPTS, MIN_BACKOFF))
+            .retryWhen(Retry.backoff(MAX_RETRY_ATTEMPTS, MIN_BACKOFF)
+                .filter(preparedStatementConflictException()))
             .map(Record1::value1);
     }
 
@@ -113,4 +119,8 @@ public class PostgresExecutor {
     public Mono<Void> dispose() {
         return connection.flatMap(con -> Mono.from(con.close()));
     }
+
+    private Predicate<Throwable> preparedStatementConflictException() {
+        return throwable -> throwable.getCause() instanceof 
R2dbcBadGrammarException;
+    }
 }


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

Reply via email to