Chapter 15. Detecting Dead Connections

This chapter discusses Connection Time-to-Live (TTL), and explains how HornetQ deals with crashed clients and clients that have exited without cleanly closing their resources.

15.1. Cleaning up Dead Connection Resources on the Server

Before a HornetQ client application exits, its resources should be closed using a finally block.

Example 15.1. Well Behaved Core Client Application

Below is an example of a well behaved core client application closing its session and session factory in a finally block:
ClientSessionFactory sf = null;
ClientSession session = null;

try
{
   sf = HornetQClient.createClientSessionFactory(...);
   session = sf.createSession(...);   
   ... do some stuff with the session...
}
finally
{
   if (session != null)
   {
      session.close();
   }
   
   if (sf != null)
   {
      sf.close();
   }
}

Example 15.2. Well Behaved JMS Client Application

This is an example of a well behaved JMS client application:
Connection jmsConnection = null;

try
{
   ConnectionFactory jmsConnectionFactory = HornetQJMSClient.createConnectionFactory(...);

   jmsConnection = jmsConnectionFactory.createConnection();

   ... do some stuff with the connection...
}
finally
{
   if (connection != null)
   {
      connection.close();
   }
}
If a client crashes, server side resources like sessions can be left hanging on the server. This can cause a resource leak over time and lead to the server running out of memory or other resources.
The requirement for cleaning up dead client resources is balanced with HornetQ client reconnection support. The network between the client and the server can fail and then reboot, allowing the client to reconnect. If the resources have been cleaned, the reboot will fail.
To ensure that resources are cleaned upon client crash, while allowing for reboot time, the connection TTL is configurable. Each ClientSessionFactory has a defined connection TTL. The TTL determines how long the server will keep a connection alive in the absence of any data arriving from the client.
The client automatically sends ping packets to prevent the server from closing it down. If the server does not receive any packets on a connection for the connection TTL time, then it will close all the sessions on the server that relate to that connection.
You can configure this functionality on the client side or the server side using the following methods:
  • On the client side, specify the ConnectionTTL attribute on a HornetQConnectionFactory instance (<JBOSS_HOME>/jboss-as/server/<PROFILE>/deploy/jms-ra.rar/META-INF/ra.xml)
  • On the server side where connection factory instances are being deployed directly into JNDI, specify the connection-ttl parameter for the <connection-factory> directive in the JBOSS_DIST/jboss-as/server/<PROFILE>/deploy/hornetq/hornetq-jms.xml file.
The default value for ConnectionTTL is 60000 (milliseconds). A value of -1 for the ConnectionTTL attribute means the server will never time out the connection on the server side.
To prevent clients specifying their own connection TTL, a global value can be set on the server side that overrides all other values. To do this, specify the connection-ttl-override attribute in JBOSS_DIST/jboss-as/server/<PROFILE>/deploy/hornetq/hornetq-jms.xml file. The default value for connection-ttl-override is -1, which allows clients to set their own values for connection TTL.

15.1.1. Closing core sessions or JMS connections that have failed to close

It is important that all core client sessions and JMS connections are always closed explicitly in a finally block when they are finished.
If a session or connection is not closed in a finally block, HornetQ will detect this at garbage collection time, and log a warning similar to the following in the logs (If you are using JMS the warning will involve a JMS connection not a client session):
[Finalizer] 20:14:43,244 WARNING [org.hornetq.core.client.impl.DelegatingSession]  
  I'm closing a ClientSession you left open. Please make sure you close all ClientSessions 
  explicitly before letting them go out of scope!
[Finalizer] 20:14:43,244 WARNING [org.hornetq.core.client.impl.DelegatingSession]  
The session you did not close was created here: 
java.lang.Exception
  at org.hornetq.core.client.impl.DelegatingSession.<init>(DelegatingSession.java:83)
  at org.acme.yourproject.YourClass (YourClass.java:666)
HornetQ will then close the connection / client session.
The log will also print the line of user code where the JMS connection/client session that did not close was created. This enables the error to be pinpointed and corrected appropriately.