users@grizzly.java.net

How to handle server that does not respond

From: Johan Maasing <johan_at_zoom.nu>
Date: Thu, 5 Jun 2014 13:23:22 +0200

I hope someone can help me understand how to handle servers that does not
respond in time. I thought that maybe IdleTimeoutFilter would handle this
but I don't see the connection close after the specified time. Am I
misunderstanding what the Idle/ActivityCheck filters are supposed to do?
What would be the correct way to set up the filters (or use something else)
to give up on the connection after a while if the server does not respond?


This is my test-client (using 2.3.13):

public class TimeoutClient {
    private TCPNIOTransport transport;
    private static final long TIMEOUT_IN_MILLIS = 2000 ;

    public static void main(String... args) throws IOException,
InterruptedException {
        TimeoutClient app = new TimeoutClient();
        app.startup();
        app.run();
    }

    private void run() throws InterruptedException {
        Thread clientThread = new Thread(() -> {
            final GrizzlyFuture<Connection> connectionGrizzlyFuture =
transport.connect("127.0.0.1", 5431);
            try {
                final Connection connection = connectionGrizzlyFuture.get();
                connection.write("");
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
        }
        );
        clientThread.start();

        Thread.sleep(TIMEOUT_IN_MILLIS * 10);
    }

    private void startup() throws IOException {
        FilterChainBuilder clientFilterChainBuilder =
FilterChainBuilder.stateless();
        clientFilterChainBuilder.add(new TransportFilter());
        clientFilterChainBuilder.add(new
IdleTimeoutFilter(IdleTimeoutFilter.createDefaultIdleDelayedExecutor(),
TIMEOUT_IN_MILLIS, TimeUnit.MILLISECONDS));
        clientFilterChainBuilder.add(new LogFilter());
        clientFilterChainBuilder.add(new
StringFilter(Charsets.UTF8_CHARSET));
        transport = TCPNIOTransportBuilder.newInstance().build();
        transport.setProcessor(clientFilterChainBuilder.build());
        transport.start();
    }
}

My test server is simply this:


public class DiscardServer {
    boolean keepRunning = true;

    public static void main(String[] args) throws Exception {
        DiscardServer app = new DiscardServer();
        app.run();
    }

    private void run() throws IOException {
        ServerSocket ss = new ServerSocket(5431);
        while (keepRunning) {
            final Socket socket = ss.accept();
            log("Server accepted a connection");
            Thread clientThread = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        try {
                            log("Will sleep for a while") ;
                            Thread.sleep(20000);
                        } catch (InterruptedException e) {
                            keepRunning = false;
                        }
                        log("Closing socket") ;
                        socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                        keepRunning = false;
                    }
                }
            });
            clientThread.start();
        }
    }

    private void log(final String msg) {
        System.out.println(System.currentTimeMillis() + " : " + msg);
    }
}

Cheers,
Johan