EsotericSoftware / kryonet

TCP/UDP client/server library for Java, based on Kryo
BSD 3-Clause "New" or "Revised" License
1.82k stars 419 forks source link

server select : 100% cpu #20

Closed ghost closed 10 years ago

ghost commented 10 years ago

From Piladong@gmail.com on May 25, 2012 04:48:18

Problem similar to issue #17 but "selector.select(timeout);" does not return 0, so the sleep is not reached. The thread loops until the next select in : for(Iterator<SelectionKey> iter = keys.iterator(); iter.hasNext();) { [...] if (udp != null && fromConnection.udpRemoteAddress == null) continue; Running KryoNet 2.09 java version "1.7.0_04" GNU/Linux x86_64 Ubuntu 9.04

Original issue: http://code.google.com/p/kryonet/issues/detail?id=19

ghost commented 10 years ago

From nathan.s...@gmail.com on May 24, 2012 23:59:09

Can you provide simple example code that reproduces the problem?

ghost commented 10 years ago

From Piladong@gmail.com on May 25, 2012 04:29:46

I had the issue after a few tries with these server/client :


import java.io.IOException; import com.esotericsoftware.kryonet.Server; public class Main { private static final int TCP_PORT = 4321; private static final int UDP_PORT = 54321;

public static void main(String[]a)
{
    try
    {
        Server server = new Server();
        server.bind(TCP_PORT, UDP_PORT);
        server.start();
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }
}

}

and a simple client :


import com.esotericsoftware.kryonet.Client;

public class Main { private static final int TCP_PORT = 4321; private static final int UDP_PORT = 54321; private static final int TIMEOUT = 5000; private static final String SERVER_IP = "xx.xx.xx.xx";

public static void main(String[]a)
{
    try
    {
        Client client = new Client();
        client.start();
        client.connect(TIMEOUT, SERVER_IP, TCP_PORT, UDP_PORT);
        for(int i = 0;i<100;++i)
        {
            client.connect(TIMEOUT, SERVER_IP, TCP_PORT, UDP_PORT);
            System.out.println("send : "+client.sendTCP("hello #"+i));
            client.close();
            Thread.sleep(10);
        }
        System.exit(0);
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
}

}

I don't understand what triggers the problem, the server's select returns something != 0 (with no timeout/thread sleep) without any client. I add a new example if i find something better for reproducing the problem.

ghost commented 10 years ago

From Piladong@gmail.com on May 25, 2012 05:18:26

I have the simple server posted above running on my server at 100% cpu with remote debug, if you want to have a look.

ghost commented 10 years ago

From Piladong@gmail.com on May 25, 2012 06:00:22

Ok i found an example that always triggers the problem. Same server as above and this client (without starting the client thread, so the registration times out) :


import com.esotericsoftware.kryonet.Client;

public class Main { private static final int TCP_PORT = 4321; private static final int UDP_PORT = 54321; private static final int TIMEOUT = 5000; private static final String SERVER_IP = "xx.xx.xx.xx";

public static void main(String[]a)
{
    try
    {
        Client client = new Client();
        client.connect(TIMEOUT, SERVER_IP, TCP_PORT, UDP_PORT);
        System.exit(0);
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
}

}

Actually the problem occurs when the client registration fails.

ghost commented 10 years ago

From nathan.s...@gmail.com on May 26, 2012 00:51:35

This issue was closed by revision r111.

Status: Fixed

ghost commented 10 years ago

From nathan.s...@gmail.com on May 26, 2012 00:53:07

Thanks a lot for the test, I see the same behavior. Reading from the channel when it is being selected repeated shows the channel is closed. I think the channel should be closed if the TCP channel is selected and UDP has not been registered. This resolves the problem.