2

I'm attempting to utilize the .NET Kaazing client in order to interact with a JMS back-end via web sockets. I'm struggling to understand the correct usage of sessions. Initially, I had a single session shared across all threads, but I noticed that this was not supported:

A Session object is a single-threaded context for producing and consuming messages. Although it may allocate provider resources outside the Java virtual machine (JVM), it is considered a lightweight JMS object.

The reason I had a single session was just because I thought that would yield better performance. Since the documentation claimed sessions were lightweight, I had no hesitation switching my code over to use a session per "operation". By "operation" I mean either sending a single message, or subscribing to a queue/topic. In the former case, the session is short-lived and closed immediately after the message is sent. In the latter case, the session needs to live as long as the subscription is active.

When I tried creating multiple sessions I got an error:

System.NotSupportedException: Only one non-transacted session can be active at a time

Googling this error was fruitless, so I tried switching over to transacted sessions. But when attempting to create a consumer I get a different error:

System.NotSupportedException: This operation is not supported in transacted sessions

So it seems I'm stuck between a rock and a hard place. The only possible options I see are to share my session across threads or to have a single, non-transacted session used to create consumers, and multiple transacted sessions for everything else. Both these approaches seem a little against the grain to me.

Can anyone shed some light on the correct way for me to handle sessions in my client?

Kent Boogaart
  • 175,602
  • 35
  • 392
  • 393

1 Answers1

0

There are several ways to add concurrency to your application. You could use multiple Connections, but that is probably not desirable due to an increase in network overhead. Better would be to implement a simple mechanism for handling the concurrency in the Message Listener by dispatching Tasks or by delivering messages via ConcurrentQueues. Here are some choices for implementation strategy:

  1. The Task based approach would use a TaskScheduler. In the MessageListener, a task would be scheduled to handle the work and return immediately. You might schedule a new Task per message, for instance. At this point, the MessageListener would return and the next message would be immediately available. This approach would be fine for low throughput applications - e.g. a few messages per second - but where you need concurrency perhaps because some messages may take a long time to process.

  2. Another approach would be to use a data structure of messages for work pending (ConcurrentQueue). When the MessageListener is invoked, each Message would be added to the ConcurrentQueue and return immediately. Then a separate set of threads/tasks can pull the messages from that ConcurrectQueue using an appropriate strategy for your application. This would work for a higher performance application.

  3. A variation of this approach would be to have a ConcurrentQueue for each Thread processing inbound messages. Here the MessageListener would not manage its own ConcurrentQueue, but instead it would deliver the messages to the ConcurrentQueue associated with each thread. For instance, if you have inbound messages representing stock feeds and also news feeds, one thread (or set of threads) could process the stock feed messages, and another could process inbound news items separately.

Note that if you are using JMS Queues, each message will be acknowledged implicitly when your MessageListener returns. This may or may not be the behavior you want for your application.

For higher performance applications, you should consider approaches 2 and 3.

Peter Moskovits
  • 4,236
  • 1
  • 20
  • 15
  • Thanks for the answer, but you don't really address my question. I am not understanding when and how to create *sessions* - concurrent handling of received messages is not my issue. My current approach is to create a single, long-lived, non-transacted session from which all consumers are created. Then, for every message I need to send, I create a short-lived, transacted session with which to send the message. This seems to work but also seems rather convoluted. Are you able to comment on my approach? – Kent Boogaart Jun 12 '12 at 15:53