Search in sources :

Example 1 with ActiveMQSessionContext

use of org.apache.activemq.artemis.core.protocol.core.impl.ActiveMQSessionContext in project activemq-artemis by apache.

the class ClientSessionFactoryImpl method failoverOrReconnect.

/**
 * TODO: Maybe this belongs to ActiveMQClientProtocolManager
 *
 * @param connectionID
 * @param me
 */
private void failoverOrReconnect(final Object connectionID, final ActiveMQException me, String scaleDownTargetNodeID) {
    ActiveMQClientLogger.LOGGER.failoverOrReconnect(connectionID, me);
    for (ClientSessionInternal session : sessions) {
        SessionContext context = session.getSessionContext();
        if (context instanceof ActiveMQSessionContext) {
            ActiveMQSessionContext sessionContext = (ActiveMQSessionContext) context;
            if (sessionContext.isKilled()) {
                setReconnectAttempts(0);
            }
        }
    }
    Set<ClientSessionInternal> sessionsToClose = null;
    if (!clientProtocolManager.isAlive())
        return;
    Lock localFailoverLock = lockFailover();
    try {
        if (connection == null || !connection.getID().equals(connectionID) || !clientProtocolManager.isAlive()) {
            return;
        }
        if (ClientSessionFactoryImpl.logger.isTraceEnabled()) {
            logger.trace("Client Connection failed, calling failure listeners and trying to reconnect, reconnectAttempts=" + reconnectAttempts);
        }
        callFailoverListeners(FailoverEventType.FAILURE_DETECTED);
        // We call before reconnection occurs to give the user a chance to do cleanup, like cancel messages
        callSessionFailureListeners(me, false, false, scaleDownTargetNodeID);
        if (reconnectAttempts != 0) {
            if (clientProtocolManager.cleanupBeforeFailover(me)) {
                // Now we absolutely know that no threads are executing in or blocked in
                // createSession,
                // and no
                // more will execute it until failover is complete
                // So.. do failover / reconnection
                RemotingConnection oldConnection = connection;
                connection = null;
                Connector localConnector = connector;
                if (localConnector != null) {
                    try {
                        localConnector.close();
                    } catch (Exception ignore) {
                    // no-op
                    }
                }
                cancelScheduledTasks();
                connector = null;
                reconnectSessions(oldConnection, reconnectAttempts, me);
                if (oldConnection != null) {
                    oldConnection.destroy();
                }
                if (connection != null) {
                    callFailoverListeners(FailoverEventType.FAILOVER_COMPLETED);
                }
            }
        } else {
            RemotingConnection connectionToDestory = connection;
            if (connectionToDestory != null) {
                connectionToDestory.destroy();
            }
            connection = null;
        }
        if (connection == null) {
            synchronized (sessions) {
                sessionsToClose = new HashSet<>(sessions);
            }
            callFailoverListeners(FailoverEventType.FAILOVER_FAILED);
            callSessionFailureListeners(me, true, false, scaleDownTargetNodeID);
        }
    } finally {
        localFailoverLock.unlock();
    }
    // This needs to be outside the failover lock to prevent deadlock
    if (connection != null) {
        callSessionFailureListeners(me, true, true);
    }
    if (sessionsToClose != null) {
        for (ClientSessionInternal session : sessionsToClose) {
            try {
                session.cleanUp(true);
            } catch (Exception cause) {
                ActiveMQClientLogger.LOGGER.failedToCleanupSession(cause);
            }
        }
    }
}
Also used : Connector(org.apache.activemq.artemis.spi.core.remoting.Connector) ActiveMQSessionContext(org.apache.activemq.artemis.core.protocol.core.impl.ActiveMQSessionContext) CoreRemotingConnection(org.apache.activemq.artemis.core.protocol.core.CoreRemotingConnection) RemotingConnection(org.apache.activemq.artemis.spi.core.protocol.RemotingConnection) ActiveMQSessionContext(org.apache.activemq.artemis.core.protocol.core.impl.ActiveMQSessionContext) SessionContext(org.apache.activemq.artemis.spi.core.remoting.SessionContext) ActiveMQNotConnectedException(org.apache.activemq.artemis.api.core.ActiveMQNotConnectedException) ActiveMQException(org.apache.activemq.artemis.api.core.ActiveMQException) ActiveMQInterruptedException(org.apache.activemq.artemis.api.core.ActiveMQInterruptedException) ReentrantLock(java.util.concurrent.locks.ReentrantLock) Lock(java.util.concurrent.locks.Lock)

Aggregations

Lock (java.util.concurrent.locks.Lock)1 ReentrantLock (java.util.concurrent.locks.ReentrantLock)1 ActiveMQException (org.apache.activemq.artemis.api.core.ActiveMQException)1 ActiveMQInterruptedException (org.apache.activemq.artemis.api.core.ActiveMQInterruptedException)1 ActiveMQNotConnectedException (org.apache.activemq.artemis.api.core.ActiveMQNotConnectedException)1 CoreRemotingConnection (org.apache.activemq.artemis.core.protocol.core.CoreRemotingConnection)1 ActiveMQSessionContext (org.apache.activemq.artemis.core.protocol.core.impl.ActiveMQSessionContext)1 RemotingConnection (org.apache.activemq.artemis.spi.core.protocol.RemotingConnection)1 Connector (org.apache.activemq.artemis.spi.core.remoting.Connector)1 SessionContext (org.apache.activemq.artemis.spi.core.remoting.SessionContext)1