log.debug("failure detected by " + source, reason);
// generate a FAILURE_DETECTED event
broadcastFailoverEvent(new FailoverEvent(FailoverEvent.FAILURE_DETECTED, source));
CreateConnectionResult res = null;
boolean failoverSuccessful = false;
boolean valveOpened = false;
int failoverEvent = FailoverEvent.FAILOVER_COMPLETED;
try
{
// block any other invocations ariving to any delegate from the hierarchy while we're
// doing failover
valve.close();
synchronized(this)
{
// testing for failed connection and setting the failed flag need to be done in one
// atomic operation, otherwise multiple threads can get to perform the client-side
// failover concurrently
if (remotingConnection.isFailed())
{
log.debug(this + " ignoring failure detection notification, as failover was " +
"already (or is in process of being) performed on this connection");
failoverSuccessful = true;
failoverEvent = FailoverEvent.FAILOVER_ALREADY_COMPLETED;
//Return true since failover already completed ok
return true;
}
remotingConnection.setFailed();
}
// Note - failover doesn't occur until _after_ the above check - so the next comment
// belongs here
log.info("JBoss Messaging server failure detected - waiting for failover to complete...");
// generate a FAILOVER_STARTED event. The event must be broadcasted AFTER valve closure,
// to insure the client-side stack is in a deterministic state
broadcastFailoverEvent(new FailoverEvent(FailoverEvent.FAILOVER_STARTED, this));
int failedNodeID = state.getServerID();
ConnectionFactoryDelegate clusteredDelegate = state.getClusteredConnectionFactoryDelegate();
// try recreating the connection
log.trace("Creating new connection");
res = clusteredDelegate.
createConnectionDelegate(state.getUsername(), state.getPassword(), failedNodeID);
log.trace("Created connection");
if (res == null)
{
// Failover did not occur
failoverSuccessful = false;
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");