Skip to content
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

Need ability to set Socket.setReuseAddress() in RubyTCPSocket.java #378

Closed
drbobbeaty opened this issue Nov 8, 2012 · 1 comment
Closed
Labels
Milestone

Comments

@drbobbeaty
Copy link

Set-Up

I'm working with the CouchRest Gem, and a massively multi-threaded, multi-process system where we are creating and closing sockets a lot. This gets us into trouble when the code hits the following lines in RubyTCPSocket.java:

try {
    // This is a bit convoluted because (1) SocketChannel.bind is only in jdk 7 and
    // (2) Socket.getChannel() seems to return null in some cases
    channel = SocketChannel.open();
    Socket socket = channel.socket();

    if (localHost != null) {
        socket.bind( new InetSocketAddress(InetAddress.getByName(localHost), localPort) );
    }

The problem is that the time from the closing of a Socket to the opening, and therefore calling of bind() on the same host/port combination is insufficient to have the OS release the socket.

Typically, you want to set SO_REUSEADDR to true and then you can very quickly reuse that same host/port address.

Proposed Solution

My ideal solution would be to have setReuseAddress() always called with true because the number of times you don't want this are few and far between. Another idea would be able to make a system default like: -Djruby.socket.reuse=true or something where we can set it to be tru for all sockets we create in that process.

try {
    // This is a bit convoluted because (1) SocketChannel.bind is only in jdk 7 and
    // (2) Socket.getChannel() seems to return null in some cases
    channel = SocketChannel.open();
    Socket socket = channel.socket();

    socket.setReuseAddress(true);
    if (localHost != null) {
        socket.bind( new InetSocketAddress(InetAddress.getByName(localHost), localPort) );
    }

The less than ideal, but very workable solution is to have options that allow this to be set before the bind() call. This is bad in that it means I have to make sure these options are exposed in every Ruby Gem that uses sockets, and that means a lot of changes for something that, for me, is really a global preference.

@headius
Copy link
Member

headius commented Aug 1, 2015

Ok, after three years I actually looked into this.

MRI does set SO_REUSEADDR by default, but only on INET_SERVER sockets (TCPServer). I'll make that change, but for other sockets where you want to reuse you'll need to set it (as in MRI).

@headius headius closed this as completed in 4d7548c Aug 6, 2015
@headius headius added this to the JRuby 9.0.1.0 milestone Aug 6, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants