in qpid-jms-client/src/main/java/org/apache/qpid/jms/provider/failover/FailoverProvider.java [533:607]
private void handleProviderFailure(final Provider provider, final ProviderException cause) {
if (closingConnection.get() || closed.get() || failed.get()) {
return;
}
serializer.execute(() -> {
if (closingConnection.get() || closed.get() || failed.get()) {
return;
}
lock.readLock().lock();
try {
// It is possible that another failed request signaled an error for the same provider
// and we already cleaned up the old failed provider and scheduled a reconnect that
// has already succeeded, so we need to ensure that we don't kill a valid provider.
if (provider == FailoverProvider.this.provider) {
LOG.debug("handling Provider failure: {}", cause.getMessage());
LOG.trace("stack", cause);
FailoverProvider.this.provider = null;
provider.setProviderListener(closedListener);
URI failedURI = provider.getRemoteURI();
try {
provider.close();
} catch (Throwable error) {
LOG.trace("Caught exception while closing failed provider: {}", error.getMessage());
}
if (reconnectControl.isReconnectAllowed(cause)) {
if (cause instanceof ProviderConnectionRedirectedException) {
ProviderConnectionRedirectedException redirect = (ProviderConnectionRedirectedException) cause;
try {
uris.addFirst(redirect.getRedirectionURI());
} catch (Exception error) {
LOG.warn("Could not construct redirection URI from remote provided information");
}
}
ProviderListener listener = this.listener;
if (listener != null) {
listener.onConnectionInterrupted(failedURI);
}
final List<FailoverRequest> pending = new ArrayList<FailoverRequest>(requests.values());
for (FailoverRequest request : pending) {
request.whenOffline(cause);
}
// Start watching for request timeouts while we are offline, unless we already are.
if (requestTimeoutTask == null) {
long sweeperInterval = getRequestSweeperInterval();
if (sweeperInterval > 0) {
LOG.trace("Request timeout monitoring enabled: interval = {}ms", sweeperInterval);
requestTimeoutTask = serializer.scheduleWithFixedDelay(
new FailoverRequestSweeper(), sweeperInterval, sweeperInterval, TimeUnit.MILLISECONDS);
}
}
triggerReconnectionAttempt();
} else {
failed.set(true);
failureCause = cause;
ProviderListener listener = this.listener;
if (listener != null) {
listener.onConnectionFailure(cause);
}
}
} else {
LOG.trace("Ignoring duplicate provider failed event for provider: {}", provider);
}
} finally {
lock.readLock().unlock();
}
});
}