This forum is now a read-only archive. All commenting, posting, registration services have been turned off. Those needing community support and/or wanting to ask questions should refer to the Tag/Forum map, and to http://spring.io/questions for a curated list of stackoverflow tags that Pivotal engineers, and the community, monitor.

How to poll messages from an inbound message adapter

We have spring integration code running on multiple jbosses. Each jboss is listening to an inbound hornet Q and the integration flow is like this:

JMS Inbound adapter -> default channel -> service activator

We don't want service activator to be processing two different messages at the same time in 2 different JVMs. We plan to implement a distributed lock using hazelcast. The lock will give exclusive access to only 1 jvm at a time to process incoming message.

My first thought is to implement a custom poller for the inbound adapter, where the custom code can acquire the lock first and then read the inbound message and pass it on for processing. If this is the correct approach, then how do I implement a custom poller for the 'message-driven-channel-adapter'

You can add an advice-chain to the poller (via the <poller> element's advice-chain attribute), and that allows you to provide Advice that wraps the poll operation. There you could add the lock acquire(before)/release(after) behavior.

There might be other options, but that is the first thing that comes to mind.

The incoming messages from the hornet Q are going to be large xml content, that cause thousands of inserts/deletes in DB. So if multiple such messages arrive around the same time then it's possible the processing of the first one hasn't completed and the inserts/deletes start happening for the second one in parallel. If not serialized we get Oracle errors like "resource busy and acquire with nowait specified".

It's not critical for us to consume such messages in parallel and serializing is acceptable for low stress on DB.

Comment

If you are using 2.2.x and, if you need access to the message content (so perhaps you can do conditional locking - say, based on the size of the message), instead of advising the poller, you can add an advice the <service-activator/> instead (request-handler-advice-chain).

It does sound like you might want to consider only having a single active poller (by setting auto-startup=false but manually starting one of them, maybe via a control bus message). Then you would need to add the behavior to start another adapter instance if the process hosting the active one fails, but that can be done.

Comment

If you are using 2.2.x and, if you need access to the message content (so perhaps you can do conditional locking - say, based on the size of the message), instead of advising the poller, you can add an advice the <service-activator/> instead (request-handler-advice-chain).

This is also a good idea and we thought about this, but the issue is that if one JVM is processing a large xml, while the other is being waited on in a different jvm (via a distributed lock), then we might lose the waiting message if jboss crashes or restarts.

We can implement this idea if there is a guarantee or a mechanism, so that the waited message, until fully processed, will stay in the source hornet queue in case the jvm crashes.