1 Reply Latest reply on Apr 14, 2009 12:10 PM by kconner

    Actions deriving from AbstractActionLifecycle need to be thr

    fady

      Hello,

      If I am not mistaken, Actions deriving from AbstractActionLifecycle need to be thread-safe. This can be demonstrated with this simple code:

      package jbossesb.test;
      
      import org.jboss.soa.esb.actions.AbstractActionLifecycle;
      import org.jboss.soa.esb.actions.ActionLifecycleException;
      import org.jboss.soa.esb.helpers.ConfigTree;
      import org.jboss.soa.esb.message.Message;
      
      public class NotThreadSafeAction extends AbstractActionLifecycle {
      
       private int _Counter;
      
       public NotThreadSafeAction(ConfigTree config) {
       _Counter = 0;
       }
      
       public Message echo(Message message) throws ActionLifecycleException {
       System.out.println("NotThreadSafeAction echo."
       + " Thread id=" + Thread.currentThread()
       + " Counter=" + _Counter);
      
       /* Save counter value at processing start */
       int startCounter = _Counter;
      
       /* Simulate some processing time */
       try {
       Thread.sleep(3000);
       } catch (InterruptedException e) {
       e.printStackTrace();
       }
      
       /* Will break if multiple threads concurrently changing member field _Counter*/
       if (_Counter != startCounter) {
       System.out.println("Counter was changed by some other thread"
       + " Thread id=" + Thread.currentThread()
       + " Counter=" + _Counter);
       throw new ActionLifecycleException("Counter was changed by some other thread");
       }
      
       _Counter++;
       return message;
       }
      
      }


      With this configuration (notice maxThreads="2" on the ESB aware listener):

      <?xml version = "1.0" encoding = "UTF-8"?>
      <jbossesb
       xmlns="http://anonsvn.labs.jboss.com/labs/jbossesb/trunk/product/etc/schemas/xml/jbossesb-1.0.1.xsd"
       parameterReloadSecs="5">
      
       <providers>
       <jms-provider name="JBossMQ" connection-factory="ConnectionFactory">
      
       <jms-bus busid="jbossesbTestGwChannel">
       <jms-message-filter dest-type="QUEUE"
       dest-name="queue/jbossesb_test_Request_gw" />
       </jms-bus>
       <jms-bus busid="jbossesbTestEsbChannel">
       <jms-message-filter dest-type="QUEUE"
       dest-name="queue/jbossesb_test_Request_esb" />
       </jms-bus>
      
       </jms-provider>
       </providers>
      
       <services>
      
       <service category="JbossebTestESB" name="SimpleListener"
       description="Test listener">
       <listeners>
       <jms-listener name="JMS-Gateway" busidref="jbossesbTestGwChannel"
       is-gateway="true" />
       <jms-listener name="JMS-ESBListener" busidref="jbossesbTestEsbChannel"
       maxThreads="2" />
       </listeners>
       <actions mep="OneWay">
       <action name="notThreadSafeAction" class="jbossesb.test.NotThreadSafeAction"
       process="echo">
       </action>
       <!-- Forward reply to JMS reply queue. -->
       <action name="jmsRouteAction" class="org.jboss.soa.esb.actions.routing.JMSRouter">
       <property name="jndiName"
       value="queue/jbossesb_test_Request_gw_reply" />
       <property name="unwrap" value="true" />
       </action>
       </actions>
       </service>
       </services>
      
      </jbossesb>



      When 2 concurrent clients send requests to the ESB, you get this type of output:


      10:35:10,468 INFO [STDOUT] NotThreadSafeAction echo. Thread id=Thread[pool-26-thread-1,5,jboss] Counter=0
      10:35:10,906 INFO [STDOUT] NotThreadSafeAction echo. Thread id=Thread[pool-26-thread-2,5,jboss] Counter=0
      10:35:13,546 INFO [STDOUT] NotThreadSafeAction echo. Thread id=Thread[pool-26-thread-1,5,jboss] Counter=1
      10:35:13,906 INFO [STDOUT] Counter was changed by some other thread Thread id=Thread[pool-26-thread-2,5,jboss] Counter=1


      If this is confirmed then I believe the user documentation (http://anonsvn.labs.jboss.com/labs/jbossesb/trunk/product/docs/ProgrammersGuide.pdf) should be more explicit about this constraint if not, then what am I missing?

      Thanks for your help


        • 1. Re: Actions deriving from AbstractActionLifecycle need to be
          kconner

          Hiya Fady.

          Any action which implements ActionLifecyle or ActionPipelineProcessor must be thread safe as there will only be a single instance of the action created per reference in the pipeline.

          If you do not implement these interfaces, directly or indirectly, then the pipeline will create a new instance for every message passing through.

          Kev