2
votes

I have a Spring Integration Mail Inbound Adapter configured to poll a POP3 email inbox for processing incoming emails with large XML file attachments. The configuration is as follows:

    <int:channel id="emailInputChannel"/> 
    <int-mail:inbound-channel-adapter id="pop3EmailAdapter" store-uri="pop3://${pop3.user}:${pop3.pwd}@${pop3.server.host}/Inbox" 
    channel="emailInputChannel" should-delete-messages="true" auto-startup="true" java-mail-properties="javaMailProperties">               
<int:poller max-messages-per-poll="1" fixed-rate="${email.poller.rate}" />
    </int-mail:inbound-channel-adapter>

    <!-- Java Mail POP3 properties -->
    <util:properties id="javaMailProperties">
      <beans:prop key="mail.debug">true</beans:prop> 
      <beans:prop key="mail.pop3.port">${pop3.server.port}</beans:prop> 
    </util:properties>

With this configuration I have noticed that the adapter uses multiple task schedulers (essentially pollers) by default. As a result, the same email gets picked up multiple times even though I have indicated that the email needs to be deleted after pickup with the should-delete-message="true". The polling rate is set to 120 seconds. The logs below show the same email being picked up within 2 seconds of each other

 07-15-2015 05:41:46,817 INFO [task-scheduler-7] AbstractMailReceiver:receive:229 | attempting to receive mail from folder [Inbox]

07-15-2015 05:51:45,455 INFO [task-scheduler-10] AbstractMailReceiver:receive:229 | attempting to receive mail from folder [Inbox]

 07-15-2015 05:51:46,994 INFO [task-scheduler-4] AbstractMailReceiver:receive:229 | attempting to receive mail from folder [Inbox]

 07-15-2015 05:51:47,655 INFO [task-scheduler-10] EmailAttachmentSplitter:extractEmailAttachments:53 | EmailAttachmentSplitter.extractEmailAttachments: Received Message with Payload javax.mail.internet.MimeMessage@15e8cbba

 07-15-2015 05:51:49,707 INFO [task-scheduler-4] EmailAttachmentSplitter:extractEmailAttachments:53 | EmailAttachmentSplitter.extractEmailAttachments: Received Message with Payload javax.mail.internet.MimeMessage@15ef73f6

Is there a way to restrict the adapter to use only one poller instead of the default multiple pollers? If so, please provide an example of how to setup the inbound mail adapter with just one poller.

1

1 Answers

0
votes

The fixed-delay is for you. From PeriodicTrigger JavaDocs:

 * To measure the interval between the
 * scheduled <emphasis>start</emphasis> time of each execution instead, set the
 * 'fixedRate' property to {@code true}.

And its source code:

@Override
public Date nextExecutionTime(TriggerContext triggerContext) {
    if (triggerContext.lastScheduledExecutionTime() == null) {
        return new Date(System.currentTimeMillis() + this.initialDelay);
    }
    else if (this.fixedRate) {
        return new Date(triggerContext.lastScheduledExecutionTime().getTime() + this.period);
    }
    return new Date(triggerContext.lastCompletionTime().getTime() + this.period);
}

Since TaskScheduler relies on the fact of date for the task to schedule, you can reach your single-thread requirements only with fixed-delay. And the next polling task will be initiated only after the finish of previous one.