private void handleProviderFailure()

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();
            }
        });
    }