JBoss 2.0 Thread model
timfox Apr 1, 2008 12:48 PMOOOPS! Sorry I accidentally deleted this thread while doing some forum housekeeping! :)
Here it is in an ugly form I'm afraid:
jmesnil said:
JBM 2 is using MINA as its remoting API.
All JMS connections and their children (session, producer, consumer) to the same JMS server use a single MINA NioSocketConnector (i.e. one single TCP socket).
This means that all the JMS resources associated to the same JMS server share the same MINA IoSession.
In turn, this means that the messages sent by 2 JMS Sessions created from the same JMS Connection are ordered globally. This is a performance-killer and less than optimal : order must be ensured at the JMS Session level only.
One potential solution is to use 1 MINA IoSession per JMS Session + 1 MINA IoSession for each JMS connection.
This solution is simple to implement.
However this means having many TCP sockets open between a JMS client and a server...
The other solution is to introduce a customized ExecutorFilter to process MINA messages in other threads than the I/O process thread and still ensure that messages associated to a JMS Session and its children are treated by the same thread.
How to implement this ExecutorFilter?
The filter will have a ThreadFactory.
When a MINA message is sent/received, we look for a thread associated to the message target (AbstractPacket.targetID).
We need to correlate the session ID based on this targetID (the target can be a JMS Producer or Consumer)
Once we got the JMS Session ID, we use it a key to look up in a Map to get a Thread in return.
If there is such a thread, we use it.
Otherwise, we get a new thread and associate it to the JMS Session ID.
We can use a WeakValueHashmap (from jboss-common) with the targetID as the key and the thread as the weak value.
Thread life cycle
We get a new thread when we see a new JMS Session ID.
However, we do not know a priori when all messages targeted to a JMS Session have been send or received.
We can parse all the messages to find one corresponding to closing the JMS Session but is not a good idea to have to parse every message to identify this few messages.
Instead, the threads can have a keep alive time (e.g. 60 seconds) before being reclaimed (and thus being removed from the WeakValueHashmap).
If a thread associated to a JMS Session ID is reclaimed while the Session is still open, we create a new one next time we receive a message with this ID.
We also need to have threads to execute JMS Connection messages.
ID correlation
For now, each JMS resources has a random UUID.
We need to be able to deduce a JMS Session ID from one of its children ID (Producer, Consumer, QueueBrowser).
Their IDs could be prepended by a JMS Session ID (e.g. <session ID>/<resource ID>).
Or we can add a new attribute to the Packet interface (e.g. resourceID) which will be set either to a JMS Connection ID (for JMS Connections) or a JMS Session ID (for JMS Sessions, Producers, Consumers & QueueBrowsers).
This resourceID will be used as the key to the WeakValueHashMap.
This latest solution avoid parsing text for every message but adds a bit to the message size.
wdyt?