Menu Search

5.4. Session

A Session object is a single-threaded context for producing and consuming messages.

Session objects are created from the Connection. Whilst Session objects are relatively lightweight, patterns utilising a single Session per message are not recommended.

The number of sessions open per connection at any one time is limited. This value is negotiated when the connection is made. It defaults to 256.

Qpid JMS Sessions have the ability to prefetch messages to improve consumer performance. This feature is described next.

5.4.1. Prefetch

Prefetch specifies how many messages the client will optimistically cache for delivery to a consumer. This is a useful parameter to tune that can improve the throughput of an application. The prefetch buffer is scoped per Session.

The size of the prefetch buffer can be tuned per Connection using the connection url option maxprefetch (or JVM wide using the system property max_prefetch). By default, prefetch defaults to 500.

There are situations when you may wish to consider reducing the size of prefetch:

  1. When using a Competing Consumers pattern, prefetch can give the appearance of unequal division of work. This will be apparent on startup when the queue has messages. The first consumer started will cache prefetch size number of messages, possibly leaving the other consumers with no initial work.

  2. When using special queue types (such as LVQs, Sorted Queue and Priority Queues). For these queue types the special delivery rules apply whilst the message resides on the Broker. As soon as the message is sent to the client it delivery order is then fixed. For example, if using a priority queue, and a prefetch of 100, and 100 messages arrive with priority 2, the broker will send these to the client. If then a new message arrives with priority 1, the broker cannot leap frog messages of the lower priority. The priority 1 message will be delivered at the front of the next batch.

  3. When message size is large and you do not wish the memory footprint of the application to grow (or suffer an OutOfMemoryError).

Finally, if using multiple MessageConsumers on a single Session, keep in mind that unless you keep polling all consumers, it is possible for some traffic patterns to result in consumer starvation and an application level deadlock. For example, if prefetch is 100, and 100 hundred messages arrive suitable for consumer A, those messages will be prefetched by the session, entirely filling the prefetch buffer. Now if the application performs a blocking MessageConsumer#receive() for Consumer B on the same Session, the application will hang indefinitely as even if messages suitable for B arrive at the Broker. Those messages can never be sent to the Session as no space is available in prefetch.

Note

Please note, when the acknowlegement mode Session#SESSION_TRANSACTED or Session#CLIENT_ACKNOWLEDGE is set on a consuming session, the prefetched messages are released from the prefetch buffer on transaction commit/rollback (in case of acknowledgement mode Session#SESSION_TRANSACTED ) or acknowledgement of the messages receipt (in case of acknowledgement mode Session#CLIENT_ACKNOWLEDGE ). If the consuming application does not commit/rollback the receiving transaction (for example, due to mistakes in application exception handling logic), the prefetched messages continue to remain in the prefetch buffer preventing the delivery of the following messages. As result, the application might stop the receiving of the messages until the transaction is committed/rolled back (for Session#SESSION_TRANSACTED ) or received messages are acknowledged (for Session#CLIENT_ACKNOWLEDGE).

5.4.2. TemporaryQueues

Qpid implements JMS temporary queues as AMQP auto-delete queues. The life cycle of these queues deviates from the JMS specification.

AMQP auto-delete queues are deleted either when the last Consumer closes, or the Connection is closed. If no Consumer is ever attached to the queue, the queue will remain until the Connection is closed.

This deviation has no practical impact on the implementation of the request/reply messaging pattern utilising a per-request temporary reply queue. The reply to queue is deleted as the application closes the Consumer awaiting the response.

Temporary queues are exposed to Management in the same way as normal queues. Temporary queue names take the form string TempQueue followed by a random UUID.

Note that TemporaryQueue#delete() merely marks the queue as deleted on within the JMS client (and prevents further use of the queue from the application), however, the Queue will remain on the Broker until the Consumer (or Connection) is closed.

5.4.3. CreateQueue

In the Qpid JMS client, Session#createQueue() accepts either a queue name, or a Binding URL. If only name is specified the destination will be resolved into binding URL: direct://amq.direct//<queue name>?routingkey=’<queue name>’&durable=’true’.

Calling Session#createQueue() has no effect on the Broker.

Reiterating the advice from the JMS javadoc, it is suggested that this method is not generally used. Instead, application should lookup Destinations declared within JNDI.

5.4.4. CreateTopic

In the Qpid JMS client, Session#createTopic() accepts either a topic name, or a Binding URL. If only name is specified the destination will be resolved into binding URL: topic://amq.topic//<topic name>?routingkey=’<topic name>’.

Calling Session#createTopic() has no effect on the Broker.

Reiterating the advice from the JMS javadoc, it is suggested that this method is not generally used. Instead, application should lookup Destinations declared within JNDI.