You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by bt...@apache.org on 2020/07/23 07:53:23 UTC

[james-project] 12/18: JAMES-3177 Applicable flags updates needs to be thread safe

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

commit dc5ecc7e0dc1ae95063ccb82eb38b2338729d34a
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Wed Jul 22 14:08:56 2020 +0700

    JAMES-3177 Applicable flags updates needs to be thread safe
---
 .../imap/processor/base/SelectedMailboxImpl.java   | 23 +++++++++++++++-------
 .../processor/base/SelectedMailboxImplTest.java    |  3 ---
 2 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/base/SelectedMailboxImpl.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/base/SelectedMailboxImpl.java
index 91fe286..1c8d8db 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/base/SelectedMailboxImpl.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/base/SelectedMailboxImpl.java
@@ -122,12 +122,13 @@ public class SelectedMailboxImpl implements SelectedMailbox, MailboxListener {
     private final Set<MessageUid> flagUpdateUids = new TreeSet<>();
     private final Flags.Flag uninterestingFlag = Flags.Flag.RECENT;
     private final Set<MessageUid> expungedUids = new TreeSet<>();
+    private final Object applicableFlagsLock = new Object();
 
     private boolean recentUidRemoved = false;
     private boolean isDeletedByOtherSession = false;
     private boolean sizeChanged = false;
     private boolean silentFlagChanges = false;
-    private ApplicableFlags applicableFlags;
+    private ApplicableFlags applicableFlags = ApplicableFlags.from(new Flags());
 
     public SelectedMailboxImpl(MailboxManager mailboxManager, EventBus eventBus, ImapSession session, MessageManager messageManager) throws MailboxException {
         this.session = session;
@@ -147,7 +148,9 @@ public class SelectedMailboxImpl implements SelectedMailbox, MailboxListener {
             .subscribeOn(Schedulers.elastic())
             .block();
 
-        applicableFlags = ApplicableFlags.from(messageManager.getApplicableFlags(mailboxSession));
+        synchronized (applicableFlagsLock) {
+            applicableFlags = applicableFlags.updateWithNewFlags(messageManager.getApplicableFlags(mailboxSession));
+        }
         try (Stream<MessageUid> stream = messageManager.search(SearchQuery.of(SearchQuery.all()), mailboxSession)) {
             uidMsnConverter.addAll(stream.collect(Guavate.toImmutableList()));
         }
@@ -236,7 +239,9 @@ public class SelectedMailboxImpl implements SelectedMailbox, MailboxListener {
         sizeChanged = false;
         flagUpdateUids.clear();
         isDeletedByOtherSession = false;
-        applicableFlags = applicableFlags.ackUpdates();
+        synchronized (applicableFlagsLock) {
+            applicableFlags = applicableFlags.ackUpdates();
+        }
     }
 
     @Override
@@ -340,20 +345,22 @@ public class SelectedMailboxImpl implements SelectedMailbox, MailboxListener {
     }
 
     @Override
-    public synchronized Flags getApplicableFlags() {
+    public Flags getApplicableFlags() {
         return applicableFlags.flags();
     }
 
     
     @Override
-    public synchronized boolean hasNewApplicableFlags() {
+    public boolean hasNewApplicableFlags() {
         return applicableFlags.updated();
     }
 
     
     @Override
     public synchronized void resetNewApplicableFlags() {
-        applicableFlags = applicableFlags.ackUpdates();
+        synchronized (applicableFlagsLock) {
+            applicableFlags = applicableFlags.ackUpdates();
+        }
     }
 
     
@@ -426,7 +433,9 @@ public class SelectedMailboxImpl implements SelectedMailbox, MailboxListener {
                 }
             }
         }
-        applicableFlags = updateApplicableFlags(applicableFlags, updated);
+        synchronized (applicableFlagsLock) {
+            applicableFlags = updateApplicableFlags(applicableFlags, updated);
+        }
         return VOID;
     }
 
diff --git a/protocols/imap/src/test/java/org/apache/james/imap/processor/base/SelectedMailboxImplTest.java b/protocols/imap/src/test/java/org/apache/james/imap/processor/base/SelectedMailboxImplTest.java
index 679add3..02fd802 100644
--- a/protocols/imap/src/test/java/org/apache/james/imap/processor/base/SelectedMailboxImplTest.java
+++ b/protocols/imap/src/test/java/org/apache/james/imap/processor/base/SelectedMailboxImplTest.java
@@ -66,7 +66,6 @@ import org.apache.james.mailbox.store.mail.model.DefaultMessageId;
 import org.apache.james.util.concurrent.NamedThreadFactory;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
 import org.mockito.stubbing.Answer;
@@ -145,7 +144,6 @@ class SelectedMailboxImplTest {
         assertThat(selectedMailbox.getLastUid().get()).isEqualTo(EMITTED_EVENT_UID);
     }
 
-    @Disabled("JAMES-3177 SelectedMailboxImpl is not thread safe")
     @Test
     void customFlagsEventShouldNotFailWhenConcurrentWithCreation() throws Exception {
         AtomicInteger successCount = new AtomicInteger(0);
@@ -158,7 +156,6 @@ class SelectedMailboxImplTest {
         assertThat(successCount.get()).isEqualTo(1);
     }
 
-    @Disabled("JAMES-3177 SelectedMailboxImpl is not thread safe")
     @Test
     void applicableFlagsShouldBeWellUpdatedWhenConcurrentWithCreation() throws Exception {
         AtomicInteger successCount = new AtomicInteger(0);


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