Search code examples
javaspring-bootspring-integration

Spring integration mail receiver poller with task executor


I have simple outlook mail receiver with poller and taskexecutor. poll every 25 secs fixed delay Max messages per poll 2 Max fetch size 1

Mailbox has 8 messages

First poll takes 2 messages and fetches one after another in thread 1. This processing completes in 10 seconds in total

After 25 seconds second poll happens which again 2 messages and does the processing similar to first poll. Here I see thread 2.

Similarly other messages are processed.

I thought in first call based on number messages there will multiple threads (based on core size) spawned and each will poll simultaneously.

But I don’t see the parallelism. Then what is the use of task executor on poller?

For my configuration I can just play with max messages to poll and fetch size if completes before the next poll that is 25 seconds. Am I right?

Also what happens if messages processing crossed 25 seconds in one poll will second poll start or will wait for first poll to finish?


Solution

  • The logic there is like this:

    private Runnable createPoller() {
        return () ->
                this.taskExecutor.execute(() -> {
                    int count = 0;
                    while (this.initialized && (this.maxMessagesPerPoll <= 0 || count < this.maxMessagesPerPoll)) {
                        if (this.maxMessagesPerPoll == 0) {
                            logger.info("Polling disabled while 'maxMessagesPerPoll == 0'");
                            break;
                        }
                        if (pollForMessage() == null) {
                            break;
                        }
                        count++;
                    }
                });
    }
    

    The point of the task executor on the poller is to perform the polling task on a separate thread and it does that indeed for all the maxMessagesPerPoll.

    The goal is to separate scheduling from processing. This way we keep TaskScheduler as free as possible from "hard" work.

    If you want to parallel message processing, then look into an ExecutorChannel instead. This way you won't need that taskExecutor on the poller, since the loop we have just discussed is going to be very "light" and would shift the work down to the mentioned channel.

    Independently of the executor configuration, it won't matter how long you process the message: we just loop and leave the scheduled thread. So, the next polling task will be performed exactly after 25 seconds of the finish of the previous.