I have a client that receives messages from a Queue. I currently have a MessageListener
that implements onMessage()
.
Once the message is received, it is processed further then saved to a Database on the onMessage()
method; the client then acknowledges the message receipt.
As long as the database is up there is no problem. But if the DB is down, the client will not acknowledge.
To cater for this, I want the client to be sending scheduled requests to the queue for any unacknowledged messages at scheduled intervals.
As it is, the only way I have of doing this is to restart the client which is not Ideal. Is there a way to trigger the queue to resend an unacknowledged message without a restart?
What i have in onMessage()
:
//code to connect to queue
try {
if (DB is available){
//process message
//save required details to DB
msg.acknowledge();
}
else{
//schedule to request same message later from queue
}
} catch (Exception e) {}
After some more research, I have stumbled on the session.recover() which I can use to trigger redelivery. I have seen there is the RedeliveryPolicy class which I can use to set message resend options. Now my code looks like:
ConnectionFactory factory = new ActiveMQConnectionFactory(url);
RedeliveryPolicy policy = new RedeliveryPolicy();
policy.setBackOffMultiplier((short) 2);
policy.setRedeliveryDelay(30000);
policy.setInitialRedeliveryDelay(60000);
policy.setUseExponentialBackOff(true);
((ActiveMQConnectionFactory)factory).setRedeliveryPolicy(policy);
final Session session = connection.createSession(false,
Session.CLIENT_ACKNOWLEDGE);
...
...
...
..
//inside onMessage()
try {
if (DB is available){
//process message
//save required details to DB
msg.acknowledge();
}
else{
session.recover();
}
} catch (Exception e) {}