-
Notifications
You must be signed in to change notification settings - Fork 3.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Unix domain socket support #1942
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,11 @@ | ||
package redis.clients.jedis; | ||
|
||
import java.io.Closeable; | ||
import java.io.File; | ||
import java.io.IOException; | ||
import java.net.InetSocketAddress; | ||
import java.net.Socket; | ||
import java.net.SocketAddress; | ||
import java.net.SocketException; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
@@ -13,6 +15,8 @@ | |
import javax.net.ssl.SSLSocket; | ||
import javax.net.ssl.SSLSocketFactory; | ||
|
||
import org.newsclub.net.unix.AFUNIXSocket; | ||
import org.newsclub.net.unix.AFUNIXSocketAddress; | ||
import redis.clients.jedis.commands.ProtocolCommand; | ||
import redis.clients.jedis.exceptions.JedisConnectionException; | ||
import redis.clients.jedis.exceptions.JedisDataException; | ||
|
@@ -37,6 +41,7 @@ public class Connection implements Closeable { | |
private SSLSocketFactory sslSocketFactory; | ||
private SSLParameters sslParameters; | ||
private HostnameVerifier hostnameVerifier; | ||
private File unixDomainSocket; | ||
|
||
public Connection() { | ||
} | ||
|
@@ -45,6 +50,10 @@ public Connection(final String host) { | |
this.host = host; | ||
} | ||
|
||
public Connection(final File unixDomainSocket) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What if we take the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See last point in above comment. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Not anything specific, rather generic. I just meant, if we had such constructor, sockets like unix domain socket, ssl or even plain socket with different configuration from Jedis could be used by users. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
We can do that, but I think the question is should we expose that to the user as part of the library? Jedis tries to do such constructs under the hood and expose other options (ssl, passwords, etc...) and sets some defaults for each of these, we would risk exposing this and making the library a bit harder (or a bit more confusing) to use. It doesn't make much difference to my case by the way, so I am not opposing this, I just want to make sure you would be okay with that (minimal) risk. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I'm not sure I follow you. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As a user, I would much rather set a minimal parameters (e.g. port number, UDS path, credentials), than creating/setting/maintaining a socket (more code and might not be setup with the best configuration unless I am an advanced user). Not the strongest argument, but this is my intuition. What do you think? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
These are my viewpoints. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Alright, sounds good, I will refactor this to allow creating it with a Socket object for advanced use-cases, will update this soon :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @mina-asham Please take a look at #2036. WDYT? |
||
this.unixDomainSocket = unixDomainSocket; | ||
} | ||
|
||
public Connection(final String host, final int port) { | ||
this.host = host; | ||
this.port = port; | ||
|
@@ -166,19 +175,27 @@ public void setPort(final int port) { | |
public void connect() { | ||
if (!isConnected()) { | ||
try { | ||
socket = new Socket(); | ||
// ->@wjw_add | ||
socket.setReuseAddress(true); | ||
socket.setKeepAlive(true); // Will monitor the TCP connection is | ||
// valid | ||
socket.setTcpNoDelay(true); // Socket buffer Whetherclosed, to | ||
// ensure timely delivery of data | ||
socket.setSoLinger(true, 0); // Control calls close () method, | ||
// the underlying socket is closed | ||
// immediately | ||
// <-@wjw_add | ||
|
||
socket.connect(new InetSocketAddress(host, port), connectionTimeout); | ||
SocketAddress socketAddress; | ||
if (unixDomainSocket == null) { | ||
socket = new Socket(); | ||
// ->@wjw_add | ||
socket.setReuseAddress(true); | ||
socket.setKeepAlive(true); // Will monitor the TCP connection is | ||
// valid | ||
socket.setTcpNoDelay(true); // Socket buffer Whetherclosed, to | ||
// ensure timely delivery of data | ||
socket.setSoLinger(true, 0); // Control calls close () method, | ||
// the underlying socket is closed | ||
// immediately | ||
// <-@wjw_add | ||
socketAddress = new InetSocketAddress(host, port); | ||
} else { | ||
// unix domain socket doesn't support above options | ||
socket = AFUNIXSocket.newStrictInstance(); | ||
socketAddress = new AFUNIXSocketAddress(unixDomainSocket); | ||
} | ||
|
||
socket.connect(socketAddress, connectionTimeout); | ||
socket.setSoTimeout(soTimeout); | ||
|
||
if (ssl) { | ||
|
@@ -201,8 +218,13 @@ public void connect() { | |
inputStream = new RedisInputStream(socket.getInputStream()); | ||
} catch (IOException ex) { | ||
broken = true; | ||
throw new JedisConnectionException("Failed connecting to host " | ||
+ host + ":" + port, ex); | ||
if (unixDomainSocket == null) { | ||
throw new JedisConnectionException("Failed connecting to host " | ||
+ host + ":" + port, ex); | ||
} else { | ||
throw new JedisConnectionException("Failed connecting to socket " | ||
+ unixDomainSocket, ex); | ||
} | ||
} | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package redis.clients.jedis.tests; | ||
|
||
import org.junit.Test; | ||
import redis.clients.jedis.Jedis; | ||
|
||
import java.io.File; | ||
|
||
import static org.junit.Assert.assertEquals; | ||
|
||
public class UDSTest { | ||
protected static File udsHost = HostAndPortUtil.getUDSServers().get(0); | ||
@Test | ||
public void testCompareTo() { | ||
Jedis jedis = new Jedis(udsHost); | ||
assertEquals("PONG", jedis.ping()); | ||
jedis.close(); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like the idea of adding one more dependency* just to support one feature.
* compile time
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I wasn't too mad about it as well, but thought it would be fine since it's a small dependency. So I think we have a few options (ordered by most to least favourite by me, but open to suggestions):
(Sorry for the delayed response, this escaped me somehow...)