Danny Angus wrote:

Are you saying that James SELECTS each message one at a time, but does
this for every message when only one has been requested?

James should either, as you say, optimise its selects into a batch or
a select which returns multiple messages, or select each message only
when it is needed.


I think in fact what happens is that all of the messages are eagerly loaded right after the client successfully authenticates (in the PASS command). POP3Handler.doPass() calls POP3Handler.stat(), which loads all of the messages in the mailbox into an ArrayList. And yes, stat() does this by executing one query per message:

   private void stat() {
       userMailbox = new ArrayList();
       userMailbox.add(DELETED);
       for (Iterator it = userInbox.list(); it.hasNext(); ) {
           String key = (String) it.next();
           *Mail mc = userInbox.retrieve(key);*
           // Retrieve can return null if the mail is no longer in the store.
           // In this case we simply continue to the next key
           if (mc == null) {
               continue;
           }
           userMailbox.add(mc);
       }
       backupUserMailbox = (ArrayList) userMailbox.clone();
   }

(It's not clear to me how this would directly cause sockets to be exhausted in the OS, though, since we're not talking about multiple in-flight connections.)

If your POP mailbox contains 5000+ messages then you're probably using it as a poor man's IMAP, which means you're only even calling TOP on a small fraction of the messages in the mailbox, and as Hasan points out the eager loading is incredibly suboptimal for this scenario. Batching would help but it seems lazy loading would help much more.

But I think if you want to lazy load messages, STAT and LIST would need to be more directly supported by the MailRepository interface (i.e. a way to batch up message size requests, for both individual messages and aggregates). I assume that interface will pretty much need to be rewritten for (efficient) IMAP support, no?

Reply via email to