I'm implementing a mail listener in java, the listener enters IDLE until a new mail arrives, it prints the email subject and goes back into IDLE immediately again.
Is there a chance that I will miss events (new emails) between the two IDLEs that I'm issuing?
For example, I've tried sleeping for 10 seconds before going into IDLE again, and within these 10 seconds I sent 2 emails to the inbox I'm monitoring, and after the 10 seconds when I went back into IDLE my MessageCountListener
only got called once, for the first email. The second was missed.
Maybe I shouldn't rely on MessageCountListener
?
messageCountListener = new MessageCountListener() {
//lets go into idle again and then handle the message
public void messagesAdded(MessageCountEvent ev) {
Message message = ev.getMessages()[0];
try {
SimpleLogger.info("New message, subject: " + message.getSubject());
} catch (MessagingException e) {
e.printStackTrace();
}
//GeneralUtility.threadSleep(8000);
startImapIdle();
}
startImapIdle()
is called initially and then gets re-called from messagesAdded()
like above.
private void startImapIdle() {
SimpleLogger.info("Idling now");
Runnable r = () -> {
try {
inboxFolder.idle(false);
} catch (FolderClosedException e) {
SimpleLogger.warn("Push Error: [DISCONNECT]", e);
GeneralUtility.threadSleep(mailListenerRetryInterval);
startListening(inboxFolder);
} catch (StoreClosedException e) {
SimpleLogger.warn("Push Error: [GLOBAL DISCONNECT]", e);
GeneralUtility.threadSleep(mailListenerRetryInterval);
initConnection();
} catch (MessagingException e) {
SimpleLogger.warn("Push Error: [NO IDLE]", e);
GeneralUtility.threadSleep(mailListenerRetryInterval);
initConnection();
} catch (Exception e) {
SimpleLogger.warn("Push Error: [UNKNOWN]", e);
GeneralUtility.threadSleep(mailListenerRetryInterval);
initConnection();
}
};
imapIdleThread = new Thread(r);
imapIdleThread.start();
}
edit: (new code)
private void startImapIdle() {
while(true) {
try {
SimpleLogger.info("Idling now");
MailUtility.ensureFolderOpen(folder);
folder.idle();
} catch (FolderClosedException e) {
SimpleLogger.warn("Push Error: [DISCONNECT]", e);
GeneralUtility.threadSleep(mailListenerRetryInterval);
startListening();
break;
} catch (StoreClosedException e) {
SimpleLogger.warn("Push Error: [GLOBAL DISCONNECT]", e);
GeneralUtility.threadSleep(mailListenerRetryInterval);
initConnection();
break;
} catch (MessagingException e) {
SimpleLogger.warn("Push Error: [NO IDLE]", e);
GeneralUtility.threadSleep(mailListenerRetryInterval);
initConnection();
break;
} catch (Exception e) {
SimpleLogger.warn("Push Error: [UNKNOWN]", e);
GeneralUtility.threadSleep(mailListenerRetryInterval);
initConnection();
break;
}
}
}
How are you doing this? The below code works pretty well.
inbox.addMessageCountListener(new MessageCountAdapter() { ... })
Of course you need to have another infinite loop something like:
while (true) { IMAPFolder f = (IMAPFolder)inbox; f.idle(); }