If I have a Spring app with a mail server inbound channel, what is the best way to process every file in every email (I poll approx. every 1 min, and fetch 1 email with multiple attachments).
Although I can apply multithreading at the receiving channel (SimpleAsyncTaskExecutor or ThreadPoolTaskExecutor) this doesn't help much because if I have 10 files attached in an email, their processing is pretty much bound to one thread.
I've been keeping this pretty synchronous until now, because I wanted to aggregate some data for every email, and send a response after all files have been processed. I believe this could also be done in a better way.
In general how can I asynchronousl开发者_开发知识库y process every file in every email, and then again asynchronously build an email reply?
Looks like you are asking for java.util.concurrent.Future
. This is a java core concept to block until a (method) result is calculated. (see JavaDoc for an example)
The Spring @Async
support the Future
concept too.
So the only think you need to do is having a method that uses @Async
takes one attachment of the Mail as argument and returns what ever is calculated in a future.
The you need to invoke all this methods for all attachments (asynchronous) and store the immediately returned future in a list. After all methods are invoked. You try to get the feature results in an new loop. After this loop is finish all attachments are proceed asynchronous.
processOneMail(List<Attachement> attachments) {
List<Future<AttachmentResult>> futures = new ArrayList...
for(Attachment attachment : attachments) {
futures.add(processOneAttachment(attachment)); //async
}
List<AttachmentResult> attachmentResults = new ArrayList...
for(Future<AttachmentResult>> future : futures) {
attachmentResults.add(future.get()); //eventually blocks
}
//now all attachments are calculated and stored in the list.
...
}
@Async
Future<AttachmentResult> processOneAttachment(Attachment attachment) {
...
}
See also: http://blog.espenberntsen.net/2010/03/08/spring-asynchronous-support/
精彩评论