Skip to content

Commit

Permalink
Tries all hosts resolved for DNS name (#2722)
Browse files Browse the repository at this point in the history
* Tries all hosts resolved for DNS name

* address code review

* Remove unused imports

* Remove IOException import

Co-authored-by: EC2 Default User <ec2-user@ip-172-31-51-106.us-west-2.compute.internal>
Co-authored-by: M Sazzadul Hoque <7600764+sazzad16@users.noreply.github.com>
  • Loading branch information
3 people authored Jan 18, 2022
1 parent afcce7c commit 2402305
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 12 deletions.
34 changes: 28 additions & 6 deletions src/main/java/redis/clients/jedis/DefaultJedisSocketFactory.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package redis.clients.jedis;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSocket;
Expand Down Expand Up @@ -51,6 +54,23 @@ public DefaultJedisSocketFactory(HostAndPort hostAndPort, JedisClientConfig conf
}
}

private void connectToFirstSuccsefulHost(Socket socket, HostAndPort hostAndPort) throws Exception {
List<InetAddress> hosts = Arrays.asList(InetAddress.getAllByName(hostAndPort.getHost()));
if (hosts.size() > 1) {
Collections.shuffle(hosts);
}
JedisConnectionException jce = new JedisConnectionException("Failed to connect to any host resolved for DNS name.");
for (InetAddress host : hosts) {
try {
socket.connect(new InetSocketAddress(host.getHostAddress(), hostAndPort.getPort()), connectionTimeout);
return;
} catch (Exception e) {
jce.addSuppressed(e);
}
}
throw jce;
}

@Override
public Socket createSocket() throws JedisConnectionException {
Socket socket = null;
Expand All @@ -62,7 +82,7 @@ public Socket createSocket() throws JedisConnectionException {
socket.setSoLinger(true, 0); // Control calls close () method, the underlying socket is closed immediately

HostAndPort _hostAndPort = getSocketHostAndPort();
socket.connect(new InetSocketAddress(_hostAndPort.getHost(), _hostAndPort.getPort()), connectionTimeout);
connectToFirstSuccsefulHost(socket, _hostAndPort);
socket.setSoTimeout(socketTimeout);

if (ssl) {
Expand All @@ -86,11 +106,13 @@ public Socket createSocket() throws JedisConnectionException {

return socket;

} catch (IOException ex) {

} catch (Exception ex) {
IOUtils.closeQuietly(socket);

throw new JedisConnectionException("Failed to create socket.", ex);
if (ex instanceof JedisConnectionException) {
throw (JedisConnectionException) ex;
} else {
throw new JedisConnectionException("Failed to create socket.", ex);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@
import org.junit.BeforeClass;
import org.junit.Test;

import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.exceptions.JedisConnectionException;

public class UnavailableConnectionTest {
Expand Down Expand Up @@ -62,9 +59,9 @@ public void testAvoidQuitInDestroyObjectForBrokenConnection() throws Interrupted
fail("Should not get connection from pool");
} catch (Exception ex) {
assertSame(JedisConnectionException.class, ex.getClass());
// assertSame(JedisConnectionException.class, ex.getCause().getClass());
// assertSame(java.net.ConnectException.class, ex.getCause().getCause().getClass());
assertSame(java.net.ConnectException.class, ex.getCause().getClass());
// assertSame(JedisConnectionException.class, ex.getCause().getClass());
// assertSame(java.net.ConnectException.class, ex.getCause().getCause().getClass());
// assertSame(java.net.ConnectException.class, ex.getCause().getClass());
}
}

Expand Down

0 comments on commit 2402305

Please sign in to comment.