Actions deriving from AbstractActionLifecycle need to be thr
fady Apr 10, 2009 4:57 AMHello,
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