I have written a scheduler to run every one minute and use IMAP (SSL) API to get all unread messages and then mark only 200 messages from it as read and then read content of each message (200) one by one. Issue I am facing is when mail box is having around 400k messages (100GB) the first command to get unread messages itself taking more than 10 mins. I am not sure if this is how imap behaves or is it something slow at mailbox or network level. Eventually my target is to read around 500k emails in 24 hours from mail box where one message will be of around 250kb and then store each HTML message in oracle DB as blob. Currently I am no where near to achieve this target. I am attaching my code below. It is processing only 50 messages in a minute. I would really appreciate if some one can guide me to fix any performance issues in my code. Also if some has experience of extracting HTML email from mail box and persisting in database using any way, It would be really helpful if you can share your knowledge. Thanks!
public void readMails() {
int arraySize = fetchSize / threadCount;
try {
FlagTerm ft = new FlagTerm(new Flags(Flags.Flag.SEEN), false);
msgs = inbox.search(ft);
if (msgs.length > fetchSize) {
batchMsgs = Arrays.copyOfRange(msgs, 0, fetchSize - 1);
} else {
batchMsgs = msgs;
}
inbox.setFlags(batchMsgs, new Flags(Flags.Flag.SEEN), true);
if (batchMsgs.length != 0) {
archiveTaskExecutor.initialize();
List<Message> tempMsgs = new ArrayList<Message>();
// Message[] tempMsgs = new Message[arraySize];
// int i = 0;
int j = batchMsgs.length;
for (Message m : batchMsgs) {
tempMsgs.add(m);
// i++;
if (tempMsgs.size() >= arraySize || j <= 1) {
archiveTaskExecutor
.execute(new ExtractAndPersist(tempMsgs
.toArray(new Message[tempMsgs.size()])));
tempMsgs = new ArrayList<Message>();
// tempMsgs = new Message[arraySize];
// i = 0;
}
j--;
}
archiveTaskExecutor.shutdown();
try {
archiveTaskExecutor.getThreadPoolExecutor()
.awaitTermination(15, TimeUnit.MINUTES);
} catch (InterruptedException e) {
archiveTaskExecutor.getThreadPoolExecutor().shutdownNow();
}
}
} catch (Exception e) {
/** revert all messages to UNREAD here **/
}
}
private class ExtractAndPersist implements Runnable {
final Logger log = Logger.getLogger(ExtractAndPersist.class);
private Message[] messages;
public ExtractAndPersist(Message[] m) {
this.messages = m;
}
@Override
public void run() {
try {
for (Message message : messages) {
if (message != null) {
String mailContent = processMessageBody(message);
status = updateMailContent(mailId, mailContent);
}
}
}
catch (Exception e) {
/** set messages as UNREAD **/
}
}
}
}