Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Executors Check TCP Connection Alive

I am trying to recognize that hosts are alive or dead with using executor in Java. In my case, I have severeal hosts which kept in a list.

My goal is to create threads with the number of hosts and checking them. When thread connect with the host, host doesnt close the connection, and sending a situation code such as 50 (dead) or 51(alive) continiously.

My problem is threads can only connect on host. For example;

I have two host 192.168.1.1 and 192.168.1.2. Threads should check both of them in the background but I can only connect in 1.1

CONNECTION

List <Host> hosts = LoadBalancer.getHostList();
ExecutorService executor = Executors.newFixedThreadPool(hosts.size());

executor.submit(()->{
    for (Host host:hosts) {
        try {
            connect(host,"message",1);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
});

Also I have syncronized setActive function inside of HOST.java

HOST.JAVA

public class Host {
    private String ip;
    private int port;
    private boolean isActive;

    public Host(String ip, int port) {
        this.ip = ip;
        this.port = port;
        this.isActive = true;
    }

    public synchronized boolean isActive() {
        return isActive;
    }

    public synchronized void setActive(boolean active) {
        isActive = active;
    }

    public String getIp() {
        return ip;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }
}

Connect function

public static void connect(Host host, String message, int mode) throws Exception {
EventLoopGroup group = new NioEventLoopGroup();
try {
    Bootstrap clientBootstrap = new Bootstrap();

    clientBootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 500);

    clientBootstrap.group(group);
    clientBootstrap.channel(NioSocketChannel.class);
    clientBootstrap.remoteAddress(new InetSocketAddress(host.getIp(), host.getPort()));

    clientBootstrap.handler(new ChannelInitializer<SocketChannel>() {
        protected void initChannel(SocketChannel socketChannel) {

            //TODO, TIMEOUT BILGISI ILE DOLDUR BURAYI
            //socketChannel.pipeline().addLast(new ReadTimeoutHandler(1));
            //socketChannel.pipeline().addLast("idleStateHandler", new IdleStateHandler(1, 1, 2));

            socketChannel.pipeline().addLast(new ClientHandler(host, message, mode));
        }
    });

    ChannelFuture channelFuture = clientBootstrap.connect().sync();
    channelFuture.channel().closeFuture().sync();
} catch (Exception e) {
    System.err.println("Connection timed out --> " + e);
    host.setActive(false); //connection kurulamadı demektir. Bir sonraki mesaj geldiğinde bu hostun açılıp açılmadığı denenecek.
} finally {
    group.shutdownGracefully().sync();
}

}

like image 458
Berkin Akaydın Avatar asked Oct 09 '18 06:10

Berkin Akaydın


People also ask

What is ThreadPool in Java?

What is ThreadPool in Java? A thread pool reuses previously created threads to execute current tasks and offers a solution to the problem of thread cycle overhead and resource thrashing.

How does thread pool executor work?

ThreadPoolExecutor is an ExecutorService to execute each submitted task using one of possibly several pooled threads, normally configured using Executors factory methods. It also provides various utility methods to check current threads statistics and control them.

How do I set timeout in ExecutorService?

ExecutorService executorService = Executors. newCachedThreadPool(); try { List<Callable<Object>> callables = new ArrayList<>(); // Add your long time task (callable) callables. add(new VaryLongTimeTask()); // Assign tasks for specific execution timeout (e.g. 2 sec) List<Future<Object>> futures = executorService.

How does executor service work in Java?

The Java ExecutorService's execute() method takes in a runnable object and performs its task asynchronously. After making the call to execute method, we call the shutdown method, which blocks any other task to queue up in the executorService. The submit() method takes in a runnable object and returns a Future object.


1 Answers

This:

executor.submit(()->{
     for (Host host:hosts) {
        try {
            connect(host,"message",1);
            } catch (Exception e) {
            e.printStackTrace();
        }
    }
});

results in all hosts being connected to in a single Thread. You want it to read something like

for (Host host: hosts) {
    executor.submit(()->{
        try {
            connect(host,"message",1);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
});
like image 182
daniu Avatar answered Oct 09 '22 23:10

daniu