perlundq/yajsync

Preconditions for adding timeout options

Closed this issue · 3 comments

Rsync supports connection and send/receive timeouts according to the following options:

--timeout=SECONDS
This option allows you to set a maximum I/O timeout in seconds. If no data is transferred for the specified time then rsync will exit. The default is 0, which means no timeout.
Exit-Code 30: Timeout in data send/receive

--contimeout=SECONDS
This option allows you to set the amount of time that rsync will wait for its connection to an rsync daemon to succeed. If the timeout is reached, rsync exits with an error.
Exit-Code 35: Timeout waiting for daemon connection

I'd like to discuss the ways how to implement these timeouts being non-familiar with NIO blocking/non-blocking.

In principle I could imagine to change the factories for plain/ssl sockets in the following way:

public class StandardChannelFactory implements ChannelFactory
{
    @Override
    public DuplexByteChannel open(String address, int remotePort)
        throws IOException
    {
        InetSocketAddress socketAddress = new InetSocketAddress(address,
                                                                remotePort);
        // SocketChannel socketChannel = SocketChannel.open(socketAddress);

        SocketChannel socketChannel = SocketChannel.open();
        socketChannel.socket().setSoTimeout(sndRcvTimeout);
        socketChannel.socket().connect(socketAddress, connectionTimeout);

        return new StandardSocketChannel(socketChannel);
    }
}
public class SSLChannel implements DuplexByteChannel
{
...
public static SSLChannel open(String address, int port) throws IOException
    {
        SocketFactory factory = SSLSocketFactory.getDefault();
        // Socket sock = factory.createSocket(address, port);
        InetSocketAddress socketAddress = new InetSocketAddress(address, port);
        Socket sock = factory.createSocket();
        sock.setSoTimeout(sndRcvTimeout);
        sock.connect(socketAddress, connectionTimeout);
        return new SSLChannel((SSLSocket) sock);
    }
...
}

After reading https://technfun.wordpress.com/2009/01/29/networking-in-java-non-blocking-nio-blocking-nio-and-io/ I think at least com.github.perlundq.yajsync.channels.net.StandardSocketChannel might have to be changed so read/write is executed on streams (seems like r/w works on the socket directly right now).

@perlundq: I didn't dig into this yet, may you can give some advice first?

After some testing I got the timeouts to work in SSLChannel and StandardSocketChannel. So no need for a feedback from your side at this point of time. If timeouts are used the StandardSocketChannel cannot work with direct byte buffers. I will consider this similar to the handling with the tls option. I will provide a pull request when beautified.

OK, that sounds interesting

Added timouts according to #43