Skip to content

Commit

Permalink
ARTEMIS-5085 use retry parameters on initial connection
Browse files Browse the repository at this point in the history
When the Core client attempts to create the initial connection to a
broker when initialConnectAttempts > 1 it will adhere to retryInterval,
but it will ignore retryIntervalMultiplier & maxRetryInterval. This
commit fixes that so that these parameters are taken into account.
  • Loading branch information
jbertram committed Oct 2, 2024
1 parent 821005a commit 0bf3463
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -764,7 +764,7 @@ private void failoverOrReconnect(final Object connectionID,
failoverRetries++;
if (failoverRetryPredicate.test(false, failoverRetries)) {
waitForRetry(failoverRetryInterval);
failoverRetryInterval = getNextRetryInterval(failoverRetryInterval);
failoverRetryInterval = serverLocator.getNextRetryInterval(failoverRetryInterval, retryIntervalMultiplier, retryInterval);
}
}
}
Expand Down Expand Up @@ -989,7 +989,7 @@ private int getConnectionWithRetry(final int reconnectAttempts, RemotingConnecti
if (waitForRetry(interval))
return count;

interval = getNextRetryInterval(interval);
interval = serverLocator.getNextRetryInterval(interval, retryIntervalMultiplier, maxRetryInterval);
} else {
logger.debug("Could not connect to any server. Didn't have reconnection configured on the ClientSessionFactory");
return count;
Expand All @@ -1000,17 +1000,6 @@ private int getConnectionWithRetry(final int reconnectAttempts, RemotingConnecti
return count;
}

private long getNextRetryInterval(long retryInterval) {
// Exponential back-off
long nextRetryInterval = (long) (retryInterval * retryIntervalMultiplier);

if (nextRetryInterval > maxRetryInterval) {
nextRetryInterval = maxRetryInterval;
}

return nextRetryInterval;
}

@Override
public boolean waitForRetry(long interval) {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -687,6 +687,7 @@ public ClientSessionFactory createSessionFactory() throws ActiveMQException {
boolean topologyArrayTried = !config.useTopologyForLoadBalancing || topologyArray == null || topologyArray.length == 0;
boolean staticTried = false;
boolean shouldTryStatic = useInitConnector();
long interval = config.retryInterval;

while (retry && !isClosed()) {
retry = false;
Expand Down Expand Up @@ -746,9 +747,10 @@ public ClientSessionFactory createSessionFactory() throws ActiveMQException {
}
}
}
if (factory.waitForRetry(config.retryInterval)) {
if (factory.waitForRetry(interval)) {
throw ActiveMQClientMessageBundle.BUNDLE.cannotConnectToServers();
}
interval = getNextRetryInterval(interval, config.retryIntervalMultiplier, config.maxRetryInterval);
retry = true;
} else {
throw e;
Expand Down Expand Up @@ -779,6 +781,18 @@ public ClientSessionFactory createSessionFactory() throws ActiveMQException {
return factory;
}

@Override
public long getNextRetryInterval(long retryInterval, double retryIntervalMultiplier, long maxRetryInterval) {
// Exponential back-off
long nextRetryInterval = (long) (retryInterval * retryIntervalMultiplier);

if (nextRetryInterval > maxRetryInterval) {
nextRetryInterval = maxRetryInterval;
}

return nextRetryInterval;
}

private void executeDiscovery() throws ActiveMQException {
boolean discoveryOK = false;
boolean retryDiscovery = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,6 @@ default void notifyNodeDown(long uniqueEventID, String nodeID) {
int getConnectorsSize();

Pair<TransportConfiguration, TransportConfiguration> selectNextConnectorPair();

long getNextRetryInterval(long retryInterval, double retryIntervalMultiplier, long maxRetryInterval);
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;

import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
Expand Down Expand Up @@ -75,4 +76,42 @@ public void testNegativeMaxTries() throws Exception {
long timeEnd = System.currentTimeMillis();
assertTrue(timeEnd - timeStart >= 500, "3 connectors, at 100 milliseconds each try, initialConnectAttempt=2, it should have waited at least 600 (- 100 from the last try that we don't actually wait, just throw ) milliseconds");
}

@Test
public void testRetryIntervalMultiplier() {
int interval = 100;
double multiplier = 10.0;
int attempts = 3;
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61610?retryInterval=" + interval + "&retryIntervalMultiplier=" + multiplier + "&initialConnectAttempts=" + attempts);
long timeStart = System.currentTimeMillis();
try {
connectionFactory.createConnection();
fail("Creating connection here should have failed");
} catch (JMSException e) {
// expected
}
long duration = System.currentTimeMillis() - timeStart;
long toWait = 1100;
assertTrue(duration >= toWait, "Waited only " + duration + "ms, but should have waiting " + toWait);
}

@Test
public void testMaxRetryInterval() {
int interval = 100;
double multiplier = 50.0;
int attempts = 3;
int maxInterval = 1000;
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61610?retryInterval=" + interval + "&retryIntervalMultiplier=" + multiplier + "&initialConnectAttempts=" + attempts + "&maxRetryInterval=" + maxInterval);
long timeStart = System.currentTimeMillis();
try {
connectionFactory.createConnection();
fail("Creating connection here should have failed");
} catch (JMSException e) {
// expected
}
long duration = System.currentTimeMillis() - timeStart;
long toWait = 1100;
assertTrue(duration >= toWait, "Waited only " + duration + "ms, but should have waited " + toWait);
assertTrue(duration <= toWait + 500, "Waited " + duration + "ms, but should have only waited " + (toWait + 500));
}
}

0 comments on commit 0bf3463

Please sign in to comment.