log.trace("No failover");
}
else
{
// recursively synchronize state
ClientConnectionDelegate newDelegate = (ClientConnectionDelegate)res.getDelegate();
log.trace("Synchronizing state");
state.getDelegate().synchronizeWith(newDelegate);
log.trace("Synchronized state");
//Now restart the connection if appropriate
//Note! we mus start the connection while the valve is still closed
//Otherwise If a consumer closing is waiting on failover to complete
//Then on failover complete the valve will be opened and closing retried on a
//different thread
//but the next line will re-start the connection so there is a race between the two
//If the restart hits after closing then messages can get delivered after consumer
//is closed
if (state.isStarted())
{
log.trace("Starting new connection");
newDelegate.startAfterFailover();
log.trace("Started new connection");
}
if(remotingConnection.getConnectionListener() != null &&
remotingConnection.getConnectionListener().getJMSExceptionListener() != null)
{
log.trace("Adding Exception Listener to new connection");
newDelegate.setExceptionListener(remotingConnection.getConnectionListener().getJMSExceptionListener());
}
log.trace("Opening valve");
valve.open();
log.trace("Opened valve");
valveOpened = true;
failoverSuccessful = true;
log.info("JBoss Messaging failover complete");
}
log.trace("failureDetected() complete");
return failoverSuccessful;
}
catch (Exception e)
{
log.error("Failover failed", e);
throw e;
}
finally
{
if (!valveOpened)
{
log.trace("finally opening valve");
valve.open();
log.trace("valve opened");
}
if (failoverSuccessful)
{
log.debug(this + " completed successful failover");
broadcastFailoverEvent(new FailoverEvent(failoverEvent, this));
}
else
{
log.debug(this + " aborted failover");
ClientConnectionDelegate connDelegate = (ClientConnectionDelegate)state.getDelegate();
connDelegate.closing(-1);
connDelegate.close();
broadcastFailoverEvent(new FailoverEvent(FailoverEvent.FAILOVER_FAILED, this));
}
}
}