I use ImapIdleChannelAdapter (6.1.0) for retrieving messages from exchange v4 email service and have noticed that after some period of time approximately 30m probably because IDLE connection lasts 30m usually, my channel loses connection as expected and doesn't reconnnect properly. I have very similar to defaults settings with .shouldReconnectAutomatically(true)
which is actually default true also though. I thought this is enough to rely on framework to reconnect or I'm missing the point somewhere? Not much information have found on it.
Spec and flow intialization:
...
private IntegrationFlowContext flowContext;
...
ImapIdleChannelAdapterSpec imapIdleChannelAdapterSpec = Mail.imapIdleAdapter(url)
.javaMailProperties(javaMailProperties)
.javaMailAuthenticator(new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
})
.shouldReconnectAutomatically(true)
.shouldMarkMessagesAsRead(false)
.autoCloseFolder(false)
.shouldDeleteMessages(false);
StandardIntegrationFlow integrationFlow = IntegrationFlow.from(imapIdleChannelAdapterSpec)
.log(LoggingHandler.Level.DEBUG)
.handle(...)
.get();
flowContext.registration(integrationFlow)
.id("ImapFor" + imap.getUsername())
.useFlowIdAsPrefix()
.register();
I could reproduce the problem against GMail, but I didn't get any lost connection. Perhaps GMail just doesn't time it out.
My problem was about a race condition with TaskScheduler
and its single thread in the pool of an auto-configured by Spring Boot ThreadPoolTaskScheduler
: the ImapIdleChannelAdapter
schedules a ReceivingTask
which enters into an IDLE
state and blocked. That ReceivingTask
calls a ImapMailReceiver
which schedules an IdleCanceler
task. And since we are blocked in the idle()
state, we don't let another task to be performed in the scheduler.
I fixed it like this in the application.properties
:
spring.task.scheduling.pool.size=10
It is not clear, thought, from your question if you use Spring Boot or not.