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:

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.

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.

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.