[kryonet] server spins when client opens too many files

50 views
Skip to first unread message

cracknut

unread,
May 10, 2010, 3:20:56 PM5/10/10
to kryonet-users
I'm also evaluating kryonet for sending Java objects across the wire
from a client to a server. So far it has been easy to use and fast.
My testing program starts numerous threads and each one executes the
testClient N times. Each call to testClient adds a listener and then
executes sendTCP(). When the client throws the error below it leaves
the server in a state that consumes tremendous CPU resources. I have
the latest kryonet update.
java.lang.RuntimeException: Error opening selector.
at com.esotericsoftware.kryonet.Client.<init>(Client.java:81)
at com.cisco.cmsg.TestKryonetClient.<init>(TestKryonetClient.java:18)
at com.cisco.cmsg.Tester$testThread.run(Tester.java:41)
Caused by: java.io.IOException: Too many open files
at sun.nio.ch.IOUtil.initPipe(Native Method)
at sun.nio.ch.KQueueSelectorImpl.<init>(KQueueSelectorImpl.java:48)
at
sun.nio.ch.KQueueSelectorProvider.openSelector(KQueueSelectorProvider.java:
20)
at java.nio.channels.Selector.open(Selector.java:209)
at com.esotericsoftware.kryonet.Client.<init>(Client.java:79)

If you need source, I'm happy to paste it.


thanks,
Will

--
You received this message because you are subscribed to the "kryonet-users" group.
http://groups.google.com/group/kryonet-users

Nate

unread,
May 10, 2010, 5:56:52 PM5/10/10
to kryone...@googlegroups.com
Hi Will,

Could you please provide an executable example that shows the problem? It sounds as if the clients are not getting closed down properly, but it would help a lot for me to see it happen.

Thanks!
-Nate

cracknut

unread,
May 10, 2010, 6:57:29 PM5/10/10
to kryonet-users
Run the class below. 3 others follow (util with shared object,
client, and server). Maybe it's my wacky monitor code in the client?
=============
package test;

import com.esotericsoftware.minlog.Log;

public class Tester {

public Tester(String msg, int reps, int threads) {
testThread tt = null;
for (int i=0; i < threads; i++) {
tt = new testThread(msg+"_"+i, reps);
tt.start();
}
}

public static void main (String[] args) {
int threads = 1;
if (args.length < 2) {
System.out.println("usage:\nTester msg-to-send repetitions
[threads]");
System.exit(1);
}
Log.set(Log.LEVEL_INFO);
if (args.length == 3)
threads = Integer.parseInt(args[2]);
new Tester(args[0], Integer.parseInt(args[1]), threads);
}

protected class testThread extends Thread {
String msg;
int reps;

public testThread(String msg, int reps) {
this.reps = reps;
this.msg = msg;
}

public void run() {
TestKryonetClient wt;
for (int i=0; i < reps; i++) {
wt = new TestKryonetClient(msg+"_"+i);
wt = null;
}
}
}
}

=================
package test;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryonet.EndPoint;

public class TestUtilKryonet {
static public final int port = 54555;

static public void register (EndPoint endPoint) {
Kryo kryo = endPoint.getKryo();
kryo.register(NetDoc.class);
kryo.register(Ack.class);
}

static public class NetDoc {
public String text;
public long number;
}

static public class Ack {
boolean requestReceived;
}
}

============
package test;

import test.TestUtilKryonet.Ack;
import test.TestUtilKryonet.NetDoc;
import com.esotericsoftware.kryonet.Client;
import com.esotericsoftware.kryonet.Connection;
import com.esotericsoftware.kryonet.Listener;
import com.esotericsoftware.minlog.Log;

public class TestKryonetClient {
Client client;

public TestKryonetClient(String msg) {
Client client = null;

try {
final Monitor monitor = new Monitor();
client = new Client(512, 256);
client.start();
TestUtilKryonet.register(client);

client.addListener(new Listener() {
public void received (Connection connection, Object obj) {
if (obj instanceof Ack) {
Ack response = (Ack)obj;
Log.info("client recv'd:
"+response.requestReceived);
synchronized(monitor) {
monitor.done = true;
monitor.notify();
}
}
}
});

client.connect(5000, "localhost", 54555, 54777);

NetDoc esd = new NetDoc();
esd.text = msg;
esd.number = 50;

client.sendTCP(esd);

if (!monitor.done)
synchronized(monitor) {
monitor.wait(5000);
}
if (!monitor.done)
Log.warn("ERROR: no ACK!");

} catch (Exception e) {
e.printStackTrace();
} finally {
if (client != null) {
if (client.isConnected())
client.close();
client.stop();
}
}
}

protected static class Monitor {
boolean done = false;
}

public static void main (String[] args) {
Log.set(Log.LEVEL_INFO);
new TestKryonetClient(args[0]);
}
}

================
package test;

import java.io.IOException;

import test.TestUtilKryonet.Ack;
import test.TestUtilKryonet.NetDoc;
import com.esotericsoftware.kryonet.Connection;
import com.esotericsoftware.kryonet.Listener;
import com.esotericsoftware.kryonet.Server;
import com.esotericsoftware.minlog.Log;

public class TestKryonetServer {
Server server;

public TestKryonetServer () throws IOException {

Server server = new Server();
server.start();
TestUtilKryonet.register(server);
server.bind(54555, 54777);

server.addListener(new Listener() {
public void received (Connection connection, Object obj) {

if (obj instanceof NetDoc) {
NetDoc esd = (NetDoc) obj;
Log.info("received: "+esd.text);
Ack response = new Ack();
response.requestReceived = true;
connection.sendTCP(response);
}
}
});
}

public static void main (String[] args) throws IOException {
Log.set(Log.LEVEL_INFO);
new TestKryonetServer();
}
}


On May 10, 2:56 pm, Nate <nathan.sw...@gmail.com> wrote:
> Hi Will,
>
> Could you please provide an executable example that shows the problem? It
> sounds as if the clients are not getting closed down properly, but it would
> help a lot for me to see it happen.
>
> Thanks!
> -Nate

Nate

unread,
May 11, 2010, 1:33:31 PM5/11/10
to kryone...@googlegroups.com
Thanks for the code.

What arguments are using to see failure? I ran this and it was OK:
new Tester("something to send", 10, 100);

I think your "if (!monitor.done)" check should only be done inside the sync block, though I doubt it causes the problems you see.

-Nate

cracknut

unread,
May 11, 2010, 7:09:07 PM5/11/10
to kryonet-users
I saw problems running with 100 repetitions and 50 threads:
Tester msg 100 50
> You received this message because you are subscribed to the "kryonet-users" group.http://groups.google.com/group/kryonet-users
Reply all
Reply to author
Forward
0 new messages