Always close a RabbitMQ connection

I see now that in the previous rabbit examples I have missed to ensure that a connection would always be closed at the end of the program. The result is that a rabbit process, under some specific circumstance, could unhappily hang until an interrupt terminates its sad life. Remember not to do the same mistake in your production code.

The typical (bad) code is something like:
// ...
try {
    Connection connection = factory.newConnection(); // 1
    Channel channel = connection.createChannel();

    // ...

    connection.close(); // 2 !! BAD !!
}
catch(IOException e) {
    // ...
}
1. A connection is created and open
2. The connection is closed

The issue is that in case of an exception after (1) but before (2), the cleanup connection code is not called, since the control jumps directly to the catch section.

The solution is pretty easy, we should add a finally clause, and clean the connection there:
// ...
try {
    Connection connection = factory.newConnection();
    // ...
    // 1
}
catch(IOException e) {
    // ...
}
finally { // 2
    try{
        if(connection != null) connection.close();
    } catch(IOException e) {} // 3
}
1. The connection cleanup is not done here anymore.
2. The finally section is always execute, whatever happens above.
3. For what said in (2), we should ensure the connection has been actually been instantiate, before calling its close() method. Besides, we have to try-catch it, since it could throws an IO exception.

For tiny test applications, this is not such an important remark. It is probably better stressing other points and leaving out this detail. But in real code, forgetting to adequately protect the connection cleanup procedure could lead to serious problems.

No comments:

Post a Comment