You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@james.apache.org by bt...@apache.org on 2023/02/22 02:48:05 UTC

[james-project] branch 3.7.x updated: JAMES-3886 Handle Mailbox counter updates failures more gracefully [3.7.x] (#1449)

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

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


The following commit(s) were added to refs/heads/3.7.x by this push:
     new 0065b2aed8 JAMES-3886 Handle Mailbox counter updates failures more gracefully [3.7.x] (#1449)
0065b2aed8 is described below

commit 0065b2aed820f33c306f8fed6f16ede3e1a691f9
Author: Benoit TELLIER <bt...@linagora.com>
AuthorDate: Wed Feb 22 09:47:59 2023 +0700

    JAMES-3886 Handle Mailbox counter updates failures more gracefully [3.7.x] (#1449)
---
 .../cassandra/mail/CassandraIndexTableHandler.java | 54 ++++++++++++++++++----
 .../mail/CassandraIndexTableHandlerTest.java       | 25 ++++++++++
 2 files changed, 69 insertions(+), 10 deletions(-)

diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraIndexTableHandler.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraIndexTableHandler.java
index 1ef7f521ee..b9733b9638 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraIndexTableHandler.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraIndexTableHandler.java
@@ -36,6 +36,8 @@ import org.apache.james.mailbox.model.MessageMetaData;
 import org.apache.james.mailbox.model.UpdatedFlags;
 import org.apache.james.mailbox.store.mail.model.MailboxMessage;
 import org.apache.james.util.streams.Iterators;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
@@ -45,6 +47,7 @@ import reactor.core.publisher.Mono;
 import reactor.util.concurrent.Queues;
 
 public class CassandraIndexTableHandler {
+    private static final Logger LOGGER = LoggerFactory.getLogger(CassandraIndexTableHandler.class);
 
     private final CassandraMailboxRecentsDAO mailboxRecentDAO;
     private final CassandraMailboxCounterDAO mailboxCounterDAO;
@@ -190,9 +193,17 @@ public class CassandraIndexTableHandler {
 
     private Mono<Void> decrementCountersOnDelete(CassandraId mailboxId, Flags flags) {
         if (flags.contains(Flags.Flag.SEEN)) {
-            return mailboxCounterDAO.decrementCount(mailboxId);
+            return mailboxCounterDAO.decrementCount(mailboxId)
+                .onErrorResume(e -> {
+                    LOGGER.error("Failed decrementing email count for {} upon delete", mailboxId.serialize());
+                    return Mono.empty();
+                });
         }
-        return mailboxCounterDAO.decrementUnseenAndCount(mailboxId);
+        return mailboxCounterDAO.decrementUnseenAndCount(mailboxId)
+            .onErrorResume(e -> {
+                LOGGER.error("Failed decrementing email count and seen for {} upon delete", mailboxId.serialize());
+                return Mono.empty();
+            });
     }
 
     private Mono<Void> decrementCountersOnDelete(CassandraId mailboxId, Collection<MessageMetaData> metaData) {
@@ -206,18 +217,31 @@ public class CassandraIndexTableHandler {
             .filter(flag -> !flag.contains(Flags.Flag.SEEN))
             .count();
 
-        return mailboxCounterDAO.remove(MailboxCounters.builder()
+        MailboxCounters counters = MailboxCounters.builder()
             .mailboxId(mailboxId)
             .count(flags.size())
             .unseen(unseenCount)
-            .build());
+            .build();
+        return mailboxCounterDAO.remove(counters)
+            .onErrorResume(e -> {
+                LOGGER.error("Failed decrementing counters {} upon delete", counters);
+                return Mono.empty();
+            });
     }
 
     private Mono<Void> incrementCountersOnSave(CassandraId mailboxId, Flags flags) {
         if (flags.contains(Flags.Flag.SEEN)) {
-            return mailboxCounterDAO.incrementCount(mailboxId);
+            return mailboxCounterDAO.incrementCount(mailboxId)
+                .onErrorResume(e -> {
+                    LOGGER.error("Failed incrementing email count and seen for {} upon save", mailboxId.serialize());
+                    return Mono.empty();
+                });
         }
-        return mailboxCounterDAO.incrementUnseenAndCount(mailboxId);
+        return mailboxCounterDAO.incrementUnseenAndCount(mailboxId)
+            .onErrorResume(e -> {
+                LOGGER.error("Failed incrementing email count and seen for {} upon save", mailboxId.serialize());
+                return Mono.empty();
+            });
     }
 
     private Mono<Void> incrementCountersOnSave(CassandraId mailboxId, Collection<Flags> flags) {
@@ -225,11 +249,16 @@ public class CassandraIndexTableHandler {
             .filter(flag -> !flag.contains(Flags.Flag.SEEN))
             .count();
 
-        return mailboxCounterDAO.add(MailboxCounters.builder()
+        MailboxCounters counters = MailboxCounters.builder()
             .mailboxId(mailboxId)
             .count(flags.size())
             .unseen(unseenCount)
-            .build());
+            .build();
+        return mailboxCounterDAO.add(counters)
+            .onErrorResume(e -> {
+                LOGGER.error("Failed incrementing counters {} upon save", counters);
+                return Mono.empty();
+            });
     }
 
     private Mono<Void> addRecentOnSave(CassandraId mailboxId, MailboxMessage message) {
@@ -253,11 +282,16 @@ public class CassandraIndexTableHandler {
             .sum();
 
         if (sum != 0) {
-            return mailboxCounterDAO.add(MailboxCounters.builder()
+            MailboxCounters counters = MailboxCounters.builder()
                 .mailboxId(mailboxId)
                 .count(0)
                 .unseen(sum)
-                .build());
+                .build();
+            return mailboxCounterDAO.add(counters)
+                .onErrorResume(e -> {
+                    LOGGER.error("Failed incrementing counters {} upon flags update", counters);
+                    return Mono.empty();
+                });
         }
         return Mono.empty();
     }
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraIndexTableHandlerTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraIndexTableHandlerTest.java
index 51519164a5..380127781f 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraIndexTableHandlerTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraIndexTableHandlerTest.java
@@ -20,6 +20,7 @@
 package org.apache.james.mailbox.cassandra.mail;
 
 import static org.apache.james.backends.cassandra.Scenario.Builder.fail;
+import static org.apache.james.backends.cassandra.StatementRecorder.Selector.preparedStatementStartingWith;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
@@ -28,6 +29,7 @@ import javax.mail.Flags;
 
 import org.apache.james.backends.cassandra.CassandraCluster;
 import org.apache.james.backends.cassandra.CassandraClusterExtension;
+import org.apache.james.backends.cassandra.StatementRecorder;
 import org.apache.james.backends.cassandra.components.CassandraModule;
 import org.apache.james.core.Username;
 import org.apache.james.mailbox.FlagsBuilder;
@@ -123,6 +125,29 @@ class CassandraIndexTableHandlerTest {
             Long actual = mailboxCounterDAO.countMessagesInMailbox(mailbox).block();
             assertThat(actual).isEqualTo(1);
         }
+
+        @Test
+        void shouldTolerateErrorsUponFlagsUpdates(CassandraCluster cassandra) throws Exception {
+            MailboxMessage message = new MessageBuilder()
+                .flags(FlagsBuilder.builder()
+                    .add(Flags.Flag.DELETED, Flags.Flag.RECENT)
+                    .add("customFlag")
+                    .build())
+                .build();
+
+            cassandra.getConf().registerScenario(fail()
+                .times(1)
+                .whenQueryStartsWith("UPDATE mailboxCounters SET count=count+1,unseen=unseen+1 WHERE mailboxId=:mailboxId;"));
+
+            StatementRecorder statementRecorder = new StatementRecorder();
+            cassandra.getConf().recordStatements(statementRecorder);
+
+            testee.updateIndexOnAdd(message, MAILBOX_ID)
+                .block();
+
+            assertThat(statementRecorder.listExecutedStatements(preparedStatementStartingWith("UPDATE mailboxCounters SET count=count+1,unseen=unseen+1 WHERE mailboxId=:mailboxId;")))
+                .hasSize(1);
+        }
     }
 
     @Test


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