The combined requirements of single-thread or multi-thread, and synchronous or asynchronous event dispatch resulted in the current Adapter SDK JMS support implementation.
When Adapter SDK started support for JMS, it provided a simple transport configuration switch (maintaining the existing
MSession,
MPublisher,
MSubscriber object model) that allowed an adapter to change transports from Rendezvous to JMS.
To achieve this, Adapter SDK abstracted many of the differences between JMS and Rendezvous. One of the key differences is JMS session. Because event queue objects do not exist in the JMS world,
MJmsSession only encapsulates
timemsConnection and its parameters. On the other hand,
MRvSession object encapsulates
tibrvTransport and
tibrvQueue.
To support MApp::nextEvent() and
MSession::nextEvent() synchronous dispatch constructs, Adapter SDK uses synchronous event dispatch calls,
tibemsMsgConsumer_ReceiveNoWait() and
tibemsMsgConsumer_ReceiveTimeout().
For multi-threaded MDispatcher asynchronous dispatch, Adapter SDK calls
tibemsMsgConsumer_ReceiveNoWait() in a loop. If a message is retrieved, it calls
tibemsMsgConsumer_ReceiveNoWait() again on the next iteration. Otherwise, it calls
tibemsMsgConsumer_ReceiveTimeout() with a maximum timeout of 50 ms and minimum timeout of 1 ms. The upper limit is to maintain good response times, and the lower limit is to prevent high CPU usage.
The single thread adapter requirement and synchronous event dispatch requirement excluded the use of the TIBCO Enterprise Message Service asynchronous event callback where a new thread is used to dispatch each incoming event.
Also, MJmsSession is associated with consumer and producer endpoint objects such that each gets its own
tibemsSession, which can be mutex protected in the MT application dispatched using
MDispatcher.
tibemsSession needs to be protected because it is not a thread safe object per the JMS specification.
Having an equal number of consumers and dispatchers on a single queue destination increases throughput (as compared to one consumer and multiple dispatchers). This is analogous to creating a group of RVDQ subscribers to increase throughput.
The difference being RVDQ works best with queue members residing in separate running processes, while JMS queue receivers can reside within a single process. The downside is that message ordering is lost.
Adapter SDK manages construction and destruction of tibemsSession objects for an MT application. This allows multi-threaded consumption and production of messages by JMS adapter to work in a way similar to a Rendezvous adapter.
Configuring or creating multiple MSubscriber endpoints for a
MJmsSession brings the similar effect of specifying multiple JMS sessions in a TIBCO ActiveMatrix BusinessWorks JMS receiver, which would create one consumer per JMS session. You can also combine this with
MDispatcher multi-threading, which would dispatch when a consumer receives on one JMS session in each
MDispatcher thread.
If multiple consumers are connected to a JMS Session at the same time, you may need to identify which connection is yours. TIBCO Adapter SDK provides two approaches to specify a unique client identifier for a JMS session.
In TIBCO Designer, there is a property messageSelector in the EMS endpoint configuration. Adapter SDK will use the value if the property is set.