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 2018/08/21 10:17:38 UTC

[12/17] james-project git commit: MAILBOX-349 Maildir mailbox cache is not thread safe

MAILBOX-349 Maildir mailbox cache is not thread safe


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/e4eddb37
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/e4eddb37
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/e4eddb37

Branch: refs/heads/master
Commit: e4eddb372a4789e13814917fb239bcd0aee09e61
Parents: ecee101
Author: Benoit Tellier <bt...@linagora.com>
Authored: Fri Aug 17 16:16:46 2018 +0700
Committer: Benoit Tellier <bt...@linagora.com>
Committed: Tue Aug 21 17:14:37 2018 +0700

----------------------------------------------------------------------
 .../mailbox/maildir/mail/MailboxCache.java      | 68 ++++++++++++++++++++
 .../maildir/mail/MaildirMailboxMapper.java      | 46 +++----------
 2 files changed, 76 insertions(+), 38 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/e4eddb37/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/MailboxCache.java
----------------------------------------------------------------------
diff --git a/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/MailboxCache.java b/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/MailboxCache.java
new file mode 100644
index 0000000..cf04c1e
--- /dev/null
+++ b/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/MailboxCache.java
@@ -0,0 +1,68 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.mailbox.maildir.mail;
+
+import java.util.ArrayList;
+
+import org.apache.james.mailbox.exception.MailboxNotFoundException;
+import org.apache.james.mailbox.maildir.MaildirId;
+import org.apache.james.mailbox.store.mail.model.Mailbox;
+import org.apache.james.mailbox.store.mail.model.impl.SimpleMailbox;
+
+public class MailboxCache {
+    /**
+     * A request-scoped list of mailboxes in order to refer to them via id
+     */
+    private final ArrayList<Mailbox> mailboxCache = new ArrayList<>();
+
+    /**
+     * Stores a copy of a mailbox in a cache valid for one request. This is to enable
+     * referring to renamed mailboxes via id.
+     * @param mailbox The mailbox to cache
+     * @return the cached mailbox
+     */
+    public synchronized Mailbox cacheMailbox(Mailbox mailbox) {
+        mailboxCache.add(new SimpleMailbox(mailbox));
+        int id = mailboxCache.size() - 1;
+        mailbox.setMailboxId(MaildirId.of(id));
+        return mailbox;
+    }
+
+    /**
+     * Retrieves a mailbox from the cache
+     * @param mailboxId The id of the mailbox to retrieve
+     * @return The mailbox
+     * @throws MailboxNotFoundException If the mailboxId is not in the cache
+     */
+    public synchronized Mailbox getCachedMailbox(MaildirId mailboxId) throws MailboxNotFoundException {
+        if (mailboxId == null) {
+            throw new MailboxNotFoundException("null");
+        }
+        try {
+            return mailboxCache.get(mailboxId.getRawId());
+        } catch (IndexOutOfBoundsException e) {
+            throw new MailboxNotFoundException(mailboxId);
+        }
+    }
+
+    public synchronized void clear() {
+        mailboxCache.clear();
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/e4eddb37/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/MaildirMailboxMapper.java
----------------------------------------------------------------------
diff --git a/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/MaildirMailboxMapper.java b/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/MaildirMailboxMapper.java
index 55092c9..b1b83f9 100644
--- a/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/MaildirMailboxMapper.java
+++ b/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/MaildirMailboxMapper.java
@@ -42,7 +42,6 @@ import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.store.mail.MailboxMapper;
 import org.apache.james.mailbox.store.mail.model.Mailbox;
-import org.apache.james.mailbox.store.mail.model.impl.SimpleMailbox;
 import org.apache.james.mailbox.store.transaction.NonTransactionalMapper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -60,13 +59,14 @@ public class MaildirMailboxMapper extends NonTransactionalMapper implements Mail
     /**
      * A request-scoped list of mailboxes in order to refer to them via id
      */
-    private final ArrayList<Mailbox> mailboxCache = new ArrayList<>();
+    private final MailboxCache mailboxCache;
 
     private final MailboxSession session;
     
     public MaildirMailboxMapper(MaildirStore maildirStore, MailboxSession session) {
         this.maildirStore = maildirStore;
         this.session = session;
+        this.mailboxCache = new MailboxCache();
     }
 
     @Override
@@ -110,13 +110,13 @@ public class MaildirMailboxMapper extends NonTransactionalMapper implements Mail
     public Mailbox findMailboxByPath(MailboxPath mailboxPath)
             throws MailboxException, MailboxNotFoundException {      
         Mailbox mailbox = maildirStore.loadMailbox(session, mailboxPath);
-        return cacheMailbox(mailbox);
+        return mailboxCache.cacheMailbox(mailbox);
     }
     
     @Override
     public Mailbox findMailboxById(MailboxId id) throws MailboxException, MailboxNotFoundException {
         MaildirId mailboxId = (MaildirId)id;
-        return getCachedMailbox(mailboxId);
+        return mailboxCache.getCachedMailbox(mailboxId);
     }
     
     @Override
@@ -131,13 +131,13 @@ public class MaildirMailboxMapper extends NonTransactionalMapper implements Mail
         for (File folder : folders) {
             if (folder.isDirectory()) {
                 Mailbox mailbox = maildirStore.loadMailbox(session, root, mailboxPath.getNamespace(), mailboxPath.getUser(), folder.getName());
-                mailboxList.add(cacheMailbox(mailbox));
+                mailboxList.add(mailboxCache.cacheMailbox(mailbox));
             }
         }
         // INBOX is in the root of the folder
         if (Pattern.matches(mailboxPath.getName().replace(MaildirStore.WILDCARD, ".*"), MailboxConstants.INBOX)) {
             Mailbox mailbox = maildirStore.loadMailbox(session, root, mailboxPath.getNamespace(), mailboxPath.getUser(), "");
-            mailboxList.add(0, cacheMailbox(mailbox));
+            mailboxList.add(0, mailboxCache.cacheMailbox(mailbox));
         }
         return mailboxList;
     }
@@ -153,7 +153,7 @@ public class MaildirMailboxMapper extends NonTransactionalMapper implements Mail
     @Override
     public MailboxId save(Mailbox mailbox) throws MailboxException {
         try {
-            Mailbox originalMailbox = getCachedMailbox((MaildirId) mailbox.getMailboxId());
+            Mailbox originalMailbox = mailboxCache.getCachedMailbox((MaildirId) mailbox.getMailboxId());
             MaildirFolder folder = maildirStore.createMaildirFolder(mailbox);
             // equals with null check
             if (originalMailbox.getName() == null ? mailbox.getName() != null : !originalMailbox.getName().equals(mailbox.getName())) {
@@ -230,7 +230,7 @@ public class MaildirMailboxMapper extends NonTransactionalMapper implements Mail
             }
             folder.setACL(session, mailbox.getACL());
         }
-        cacheMailbox(mailbox);
+        mailboxCache.cacheMailbox(mailbox);
         return mailbox.getMailboxId();
     }
 
@@ -260,36 +260,6 @@ public class MaildirMailboxMapper extends NonTransactionalMapper implements Mail
         mailboxCache.clear();
     }
     
-    /**
-     * Stores a copy of a mailbox in a cache valid for one request. This is to enable
-     * referring to renamed mailboxes via id.
-     * @param mailbox The mailbox to cache
-     * @return The id of the cached mailbox
-     */
-    private Mailbox cacheMailbox(Mailbox mailbox) {
-        mailboxCache.add(new SimpleMailbox(mailbox));
-        int id = mailboxCache.size() - 1;
-        ((SimpleMailbox) mailbox).setMailboxId(MaildirId.of(id));
-        return mailbox;
-    }
-    
-    /**
-     * Retrieves a mailbox from the cache
-     * @param mailboxId The id of the mailbox to retrieve
-     * @return The mailbox
-     * @throws MailboxNotFoundException If the mailboxId is not in the cache
-     */
-    private Mailbox getCachedMailbox(MaildirId mailboxId) throws MailboxNotFoundException {
-        if (mailboxId == null) {
-            throw new MailboxNotFoundException("null");
-        }
-        try {
-            return mailboxCache.get(mailboxId.getRawId());
-        } catch (IndexOutOfBoundsException e) {
-            throw new MailboxNotFoundException(mailboxId);
-        }
-    }
-    
     private void visitUsersForMailboxList(File domain, File[] users, List<Mailbox> mailboxList) throws MailboxException {
         
         String userName = null;


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