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/21 01:17:15 UTC

[james-project] branch master updated: JAMES-3886 Handle Mailbox counter updates failures more gracefully (#1445)

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 6a601becc2 JAMES-3886 Handle Mailbox counter updates failures more gracefully (#1445)
6a601becc2 is described below

commit 6a601becc25343f60dacd23839dedf9c4472bc0a
Author: Benoit TELLIER <bt...@linagora.com>
AuthorDate: Tue Feb 21 08:17:09 2023 +0700

    JAMES-3886 Handle Mailbox counter updates failures more gracefully (#1445)
---
 .../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 b16a020e54..413ae25ed2 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
@@ -34,6 +34,8 @@ import org.apache.james.mailbox.model.MailboxCounters;
 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.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
@@ -43,6 +45,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;
@@ -195,9 +198,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) {
@@ -211,18 +222,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) {
@@ -230,11 +254,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) {
@@ -264,11 +293,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 524661e12f..9ce0044338 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