I have a Spring Integration directory poller:
<task:executor id="filePollingExecutor" pool-size="1" />
<int:channel id="inboundFilesChannel" datatype="java.io.File" />
<int-file:inbound-channel-adapter id="inboundFilesAdapter"
channel="inboundFilesChannel"
directory="/my/files/queue"
prevent-duplicates="true">
<int:poller id="poller" fixed-delay="1000"
max-messages-per-poll="1"
task-executor="filePollingExecutor" />
</int-file:inbound-channel-adapter>
In response to files appearing in the directory, I have a service activator which invokes a method on a service:
Unfortunately I'm finding that the service is consistently being called twice when a file arrives. Originally I thought this was due to having multiple executor threads, but you may notice above, I attempted to resolve that by tying the poller to a taskExecutor with a pool size of 1.
What I have been finding is that I can workaround the issue by increasing the delay between polls. I think the key is that it's longer than the time it takes to process a file.
<int:poller id="poller" fixed-delay="10000"
max-messages-per-poll="100"
task-executor="filePollingExecutor" />
However, that feels like a kludge rather than a fix.
Am I missing some configuration that I should be using to prevent duplicates?
It's possibly worth noting that I did try using a nio-locker
, but the issue there is that part of the processing involves sending an email with the file attached to it. File locks prevented that from being done, as the file ceased to be readable for the duration of the lock.
This answer is based on the tip from Gary Russell in the comments above.
The reason for double-processing of files is that the root and web configs were both initialising file system listeners, and therefore processing each file twice.
My approach to avoiding having the file listeners in multiple contexts was as follows.
First define a web config which only picks up classes under the "web" package.
Create separate root configs which only load beans which are not in the "web" package. i.e.
An additional factor in the configuration that took a little while to work out, was that my servlet filters and web security config needed to be in the 'root' context rather than the web context.