Quantcast
Channel: Spring Community Forums - JMS
Viewing all articles
Browse latest Browse all 51

Thread un-safety in jms:outbound-gateway with reply listener?

$
0
0
***My apologies for the double-post. I did not notice the JMS sub-forum at first***

Hello:

I've been using SI for a while now with great success, but recently heavier loading has exposed a problem in my JMS outbound-gateway with a reply listener. The problem seems to occur when the loading causes more than one thread to overlap on invoking the gateway.

I have set up a unit test where I beat on this gateway with multiple threads. In this test the request/reply payload and the service activator are both stubs of no consequence. If I serialize the messaging everything works perfectly fine. If I allow the threads to hit the gateway in parallel things go south very quickly. The problem manifests as replies that are not being correlated correctly or otherwise being discarded (they are being de-queued), then reply timeouts occur.

I am still trying to debug through it, but between the multithreading and the asynchronous behaviors it is a beast to follow. Any help you could offer would be greatly appreciated.

Below is the relevant config. Does anything jump out at you? Please note that it works flawlessly outside of multithreading, so we can skip the basic invalid configuration questions.

Code:


        <!-- The outbound gateway bean -->
        <int:gateway id="asyncActionRequestGateway"
                service-interface="xxx">
                <int:method name="executeAsyncAction" request-channel="asyncActionRequestChannel" />
        </int:gateway>

        <!-- The request channel -->
        <!-- 'integrationListenerTaskExecutor' is prototype-scoped -->
        <int:channel id="asyncActionRequestChannel">
                <int:dispatcher task-executor="integrationListenerTaskExecutor"/>
        </int:channel>


        <!-- The reply channel -->
        <!-- 'integrationListenerTaskExecutor' is prototype scoped -->
        <int:channel id="asyncActionReplyChannel">
                <int:dispatcher task-executor="integrationListenerTaskExecutor"/>
        </int:channel>
       

        <!-- The outbound JMS rigging -->
        <!-- ${integration.listener.threads.maximum} == 'integrationListenerTaskExecutor'.corePoolSize -->
        <int-jms:outbound-gateway request-channel="asyncActionRequestChannel"
                request-destination-name="${jms.destination.name.asyncactionrequest}"
                reply-channel="asyncActionReplyChannel" reply-destination-name="${jms.destination.name.asyncactionreply}"
                message-converter="asyncActionMessageConverter" header-mapper="asyncActionMessageConverter"
                reply-timeout="${bpm.actionservice.reply.timeout}" receive-timeout="${bpm.actionservice.receive.timeout}">
                <int-jms:reply-listener concurrent-consumers="${integration.listener.threads.maximum}" />
        </int-jms:outbound-gateway>


        <!-- The inbound JMS rigging -->
        <!-- ${integration.listener.threads.maximum} == 'integrationListenerTaskExecutor'.corePoolSize -->
        <int-jms:inbound-gateway request-channel="asyncActionRequestChannel"
                request-destination-name="${jms.destination.name.asyncactionrequest}"
                reply-channel="asyncActionReplyChannel" selector="${jms.asyncaction.selector.expression}"
                concurrent-consumers="${integration.listener.threads.maximum}"
                reply-timeout="${bpm.actionservice.reply.timeout}"
                receive-timeout="${bpm.actionservice.receive.timeout}"
                request-timeout="${bpm.actionservice.request.timeout}" />


Viewing all articles
Browse latest Browse all 51

Trending Articles