Announcement Announcement Module
Collapse
No announcement yet.
DefaultMessageListenerContainer102 not creating new threads Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • DefaultMessageListenerContainer102 not creating new threads

    I am trying to use DefaultMessageListenerContainer102's functionality to provide scalability (creating new threads for supporting large number of messages in queue).

    Configuration is the following:

    Code:
    <bean id="moduleA-message-listener" class="myapp.jms.MyAppMessageListenerAdapter">
    	<constructor-arg ref="myapp-moduleA-message-delegate"/>
    	<property name="defaultListenerMethod" value="receive"/>    
    	<property name="messageConverter" ref="myapp-message-converter"/>
    	<property name="defaultResponseDestination" ref="moduleA-response-queue"/>   
    	<property name="timeToLive" value="300000"/>    
    </bean>
    
    <bean id="moduleA-message-container"
      class="org.springframework.jms.listener.DefaultMessageListenerContainer102">
    	  <property name="concurrentConsumers" value="1"/>
    	  <property name="maxConcurrentConsumers" value="50"/>
    	  <property name="connectionFactory" ref="test-moduleA-connectionFactory" />
    	  <property name="destination" ref="moduleA-request-queue" />
    	  <property name="messageListener" ref="moduleA-message-listener" />
    </bean>
    I think there's something very wrong in my thinking. MyAppMessageListenerAdapter extends MessageListenerAdapter102 to send response after logic in myapp-moduleA-message-delegate is processed. I think that it will never happened that DefaultMessageListenerContainer extends thread pool responsible for handling messages. MyAppMessageListenerAdapter blocks thread until it finishes.

    From what I think this is what happens after receiving a message. Lets's say that there is only one consumer created so far, its property idle is set to true.

    1. AbstractPollingMessageListenerContainer.doReceiveA ndExecute is called, message is received by receiveMessage
    2. AsyncMessageListenerInvoker instance is used to process message. It finally invokes my adapter (by receiveAndExecite), which blocks thread until it finishes
    3. adapter finishes its work and returns to AsyncMessageListenerInvoker. NOW its flag 'idle' is set to false. This is too late!

    Thread is being blocked until message is handled. It cannot receive any messages, so it cannot create new threads for them.

    I believe that setting this.idle to false in method invokeListener after receiveAndExecite is a feature, not a bug. But I don't see how to use this feature, which results in totally not scalable application.

    How to handle this?
    Last edited by feat; Oct 17th, 2007, 03:10 AM. Reason: perhaps there is a bug in Spring, changed title to highliht it

  • #2
    Sure not a bug?

    I modified slightly AsyncMessageListenerInvoker class, so that now it looks the following way:

    Code:
    private boolean invokeListener() throws JMSException {
    	initResourcesIfNecessary();
    	this.idle = false; // retrieving message --> not idle 
    	boolean messageReceived = receiveAndExecute(this.session, this.consumer);
    	this.lastMessageSucceeded = true;
    	this.idle = !messageReceived;
    	return messageReceived;
    }
    Please note highlighted line I added. This way new thread is created *before* last idle thread stucks with time consuming processing in message delegate. It makes much more sense to me.

    Are you sure setting this.idle *after* processing message is not a bug in Spring?

    Comment

    Working...
    X