In the below 7.1.7 Asynchronous polling section of Spring Integration doc, memory leak might occur if Poller and TaskExecutor are not in tune is explained. But I did not understand it.
<int:service-activator input-channel="publishChannel" ref="myService">
<int:poller receive-timeout="5000" task-executor="taskExecutor" fixed-rate="50"/>
</int:service-activator>
<task:executor id="taskExecutor" pool-size="20" queue-capacity="20"/>
The above configuration demonstrates one of those out of tune configurations.
The poller keeps scheduling new tasks even though all the threads are blocked waiting for either a new message to arrive, or the timeout to expire. Given that there are 20 threads executing tasks with a 5 second timeout, they will be executed at a rate of 4 per second (5000/20 = 250ms). But, new tasks are being scheduled at a rate of 20 per second, so the internal queue in the task executor will grow at a rate of 16 per second (while the process is idle), so we essentially have a memory leak.
One of the ways to handle this is to set the queue-capacity attribute of > the Task Executor to 0.
Can someone please elaborate it.
Here is my understanding of the above code:
pool-size is 20 - so 20 threads will execute.
receive-timeout is 5 seconds: So 20 threads will be given 5 seconds to complete the tasks.
fixed rate is 50 ms - so new tasks are being scheduled at a rate of 20 per second.
I have few questions:
Q. what will happen if it takes more than 5 seconds to execute 20 threads?
Q. In the doc, its said tasks will be executed at a rate of 4 per second. But, some tasks might run in less than 4 seconds and some take more time.
Q. How it causes memory leak? If there are no threads and queue available, Executor rejects it as per rejection policy instead.
Q. How setting queue-capacity to 0 helps here? As per my understanding, If all threads are busy then Executor will put them in queue until it reaches queue-capacity.
The documentation is incorrect - the memory leak is only if you have an unbounded queue and the message processing can't keep up. I opened a JIRA Issue to correct it.