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?
View the original post :
http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4140578#...
Reply to the post :
http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&a...