Non Blocking Server - 100% CPU Usage without OP_WRITE

R

rajatag

Hi Everyone,

I have a non blocking server which accepts new connections as per the
acceptConnections() method below.

Connections are closed by calling channel.socket().close();

The server works fine, however after sometime we notice that the CPU
usage becomes 100% even though the server continues to function
normally.

I assume that this is due to the channels not being closed after being
registered for an OP_WRITE. However, I am not sure why that would
occur.

If someone can help it would be great!

Thanks!
Rajat

=======================

public void acceptConnections() throws IOException,
InterruptedException {

SelectionKey acceptKey =
this.selectableChannel.register(this.selector,SelectionKey.OP_ACCEPT);

while ((this.keysAdded = acceptKey.selector().select()) > 0) {
Set readyKeys = this.selector.selectedKeys();
Iterator i = readyKeys.iterator();

while (i.hasNext()) {
try {
SelectionKey key = (SelectionKey) i.next();
i.remove();
if (key.isAcceptable()) {
ServerSocketChannel nextReady = (ServerSocketChannel) key
.channel();

SocketChannel channel = nextReady.accept();

if (db.checkIPBanning(channel.socket().getInetAddress()
.toString())) {
channel.configureBlocking(false);
SelectionKey readKey = channel.register(
this.selector, SelectionKey.OP_READ);

readKey.attach(new ClientConnection(this, channel,
"" + channel.socket().getPort()
+ channel.socket().getInetAddress()
+ ran.nextInt()));
} else {
channel.socket().close();
System.out.println("Banned IP ... "
+ channel.socket().getInetAddress()
.toString());
}

} else if (key.isReadable()) {
try {
this.readMessage((ClientConnection) key
.attachment());
} catch (Exception e) {
key.channel().close();
}
}
} catch (Exception e) {
}
}

}
}
 
G

Gordon Beaton

The server works fine, however after sometime we notice that the CPU
usage becomes 100% even though the server continues to function
normally.

I assume that this is due to the channels not being closed after
being registered for an OP_WRITE. However, I am not sure why that
would occur.

Why do you assume this? I don't see OP_WRITE mentioned in your code.
else if (key.isReadable()) {
try {
this.readMessage( (ClientConnection)key.attachment() );
}
catch (Exception e) {
key.channel().close();
}
}

What does readMessage() do when it reaches EOF?

/gordon
 
R

rajatag

1. I was assuming OP_WRITE because at one point I had set OP_WRITE with
OP_READ and it lead to 100% CPU usage.


2. Here is the code for readMessage(). It is set to call a function
when it encounters end of line. I guess EOF is handled by default?

public void readMessage(ClientConnection callback) throws IOException,
InterruptedException {
ByteBuffer byteBuffer = ByteBuffer.allocate(BUFSIZE);
callback.getChannel().read(byteBuffer);
byteBuffer.flip();
String result = this.decode(byteBuffer);
callback.append(result.toString());
if (result.indexOf("\n") >= 0)
callback.process();
}

Thanks!
 
G

Gordon Beaton

2. Here is the code for readMessage(). It is set to call a function
when it encounters end of line. I guess EOF is handled by default?

public void readMessage(ClientConnection callback) throws IOException,
InterruptedException {
ByteBuffer byteBuffer = ByteBuffer.allocate(BUFSIZE);
callback.getChannel().read(byteBuffer);
byteBuffer.flip();
String result = this.decode(byteBuffer);
callback.append(result.toString());
if (result.indexOf("\n") >= 0)
callback.process();
}

If a client crashes or simply closes the socket, Channel.read() will
reach EOF and return -1, and no exception will be raised.

You should *always* check the return value from read().

If you fail to close the channel after reaching EOF, the channel will
remain readable and the selector loop will spin.

/gordon
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top