/* Hook for creating session factory */ protected ClientSessionFactoryInternal createSessionFactory() throws Exception { if (targetNodeID != null && (this.reconnectAttemptsSameNode < 0 || retryCount <= this.reconnectAttemptsSameNode)) { csf = reconnectOnOriginalNode(); } else { serverLocator.resetToInitialConnectors(); csf = (ClientSessionFactoryInternal) serverLocator.createSessionFactory(); } // null here means the targetNodeIS is not available yet if (csf != null) { csf.setReconnectAttempts(0); } return csf; }
@Test public void testNoAutoFailback() throws Exception { locator .setBlockOnNonDurableSend(true) .setBlockOnDurableSend(true) .setFailoverOnInitialConnection(true) .setReconnectAttempts(-1); ClientSessionFactoryInternal sf = createSessionFactoryAndWaitForTopology(locator, 2); ClientSession session = sendAndConsume(sf, true); CountDownSessionFailureListener listener = new CountDownSessionFailureListener(1, session); session.addFailureListener(listener); backupServer.stop(); liveServer.crash(); backupServer.start(); assertTrue(listener.getLatch().await(5, TimeUnit.SECONDS)); ClientProducer producer = session.createProducer(ADDRESS); ClientMessage message = session.createMessage(true); setBody(0, message); producer.send(message); session.removeFailureListener(listener); Thread t = new Thread(new ServerStarter(liveServer)); t.start(); waitForRemoteBackup(sf, 10, false, backupServer.getServer()); assertTrue(backupServer.isStarted()); backupServer.crash(); waitForServerToStart(liveServer.getServer()); assertTrue(liveServer.isStarted()); sf.close(); assertEquals(0, sf.numSessions()); assertEquals(0, sf.numConnections()); }
protected void scheduleRetryConnect() { if (serverLocator.isClosed()) { ActiveMQServerLogger.LOGGER.bridgeLocatorShutdown(); return; } if (stopping) { ActiveMQServerLogger.LOGGER.bridgeStopping(); return; } if (reconnectAttemptsInUse >= 0 && retryCount > reconnectAttemptsInUse) { ActiveMQServerLogger.LOGGER.bridgeAbortStart(name, retryCount, reconnectAttempts); fail(true); return; } long timeout = (long) (this.retryInterval * Math.pow(this.retryMultiplier, retryCount)); if (timeout == 0) { timeout = this.retryInterval; } if (timeout > maxRetryInterval) { timeout = maxRetryInterval; } logger.debug( "Bridge " + this + " retrying connection #" + retryCount + ", maxRetry=" + reconnectAttemptsInUse + ", timeout=" + timeout); scheduleRetryConnectFixedTimeout(timeout); }
private ClientSessionFactoryInternal reconnectOnOriginalNode() throws Exception { String targetNodeIdUse = targetNodeID; TopologyMember nodeUse = targetNode; if (targetNodeIdUse != null && nodeUse != null) { TransportConfiguration[] configs = new TransportConfiguration[2]; // live and backup int numberOfConfigs = 0; if (nodeUse.getLive() != null) { configs[numberOfConfigs++] = nodeUse.getLive(); } if (nodeUse.getBackup() != null) { configs[numberOfConfigs++] = nodeUse.getBackup(); } if (numberOfConfigs > 0) { // It will bounce between all the available configs int nodeTry = (retryCount - 1) % numberOfConfigs; return (ClientSessionFactoryInternal) serverLocator.createSessionFactory(configs[nodeTry]); } } return null; }
/* This is called only when the bridge is activated */ protected void connect() { if (stopping) return; synchronized (connectionGuard) { if (!keepConnecting) return; logger.debug( "Connecting " + this + " to its destination [" + nodeUUID.toString() + "], csf=" + this.csf); retryCount++; try { if (csf == null || csf.isClosed()) { if (stopping) return; csf = createSessionFactory(); if (csf == null) { // Retrying. This probably means the node is not available (for the cluster connection // case) scheduleRetryConnect(); return; } // Session is pre-acknowledge session = (ClientSessionInternal) csf.createSession(user, password, false, true, true, true, 1); sessionConsumer = (ClientSessionInternal) csf.createSession(user, password, false, true, true, true, 1); } if (forwardingAddress != null) { ClientSession.AddressQuery query = null; try { query = session.addressQuery(forwardingAddress); } catch (Throwable e) { ActiveMQServerLogger.LOGGER.errorQueryingBridge(e, name); // This was an issue during startup, we will not count this retry retryCount--; scheduleRetryConnectFixedTimeout(100); return; } if (forwardingAddress.startsWith(BridgeImpl.JMS_QUEUE_ADDRESS_PREFIX) || forwardingAddress.startsWith(BridgeImpl.JMS_TOPIC_ADDRESS_PREFIX)) { if (!query.isExists()) { ActiveMQServerLogger.LOGGER.errorQueryingBridge(forwardingAddress, retryCount); scheduleRetryConnect(); return; } } else { if (!query.isExists()) { ActiveMQServerLogger.LOGGER.bridgeNoBindings( getName(), getForwardingAddress(), getForwardingAddress()); } } } producer = session.createProducer(); session.addFailureListener(BridgeImpl.this); session.setSendAcknowledgementHandler(BridgeImpl.this); afterConnect(); active = true; queue.addConsumer(BridgeImpl.this); queue.deliverAsync(); ActiveMQServerLogger.LOGGER.bridgeConnected(this); // We only do this on plain core bridges if (isPlainCoreBridge()) { serverLocator.addClusterTopologyListener(new TopologyListener()); } keepConnecting = false; return; } catch (ActiveMQException e) { // the session was created while its server was starting, retry it: if (e.getType() == ActiveMQExceptionType.SESSION_CREATION_REJECTED) { ActiveMQServerLogger.LOGGER.errorStartingBridge(name); // We are not going to count this one as a retry retryCount--; scheduleRetryConnectFixedTimeout(this.retryInterval); return; } else { if (logger.isDebugEnabled()) { logger.debug("Bridge " + this + " is unable to connect to destination. Retrying", e); } scheduleRetryConnect(); } } catch (ActiveMQInterruptedException | InterruptedException e) { ActiveMQServerLogger.LOGGER.errorConnectingBridge(e, this); } catch (Exception e) { ActiveMQServerLogger.LOGGER.errorConnectingBridge(e, this); if (csf != null) { try { csf.close(); csf = null; } catch (Throwable ignored) { } } fail(false); scheduleRetryConnect(); } } }