Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / August 2006

Tip: Looking for answers? Try searching our database.

Non Blocking Server - 100% CPU Usage without OP_WRITE

Thread view: 
rajatag - 25 Aug 2006 10:06 GMT
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) {
            }
        }

    }
}
Gordon Beaton - 25 Aug 2006 10:29 GMT
> The server works fine, however after sometime we notice that the CPU
> usage becomes 100% even though the server continues to function
[quoted text clipped - 3 lines]
> 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 {
[quoted text clipped - 4 lines]
>   }
> }

What does readMessage() do when it reaches EOF?

/gordon

Signature

[ don't email me support questions or followups ]
g o r d o n  +  n e w s  @  b a l d e r 1 3 . s e

rajatag - 25 Aug 2006 11:57 GMT
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!
Gordon Beaton - 25 Aug 2006 12:20 GMT
> 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?
[quoted text clipped - 9 lines]
>             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

Signature

[ don't email me support questions or followups ]
g o r d o n  +  n e w s  @  b a l d e r 1 3 . s e

rajatag - 25 Aug 2006 12:51 GMT
Thanks for the help. I will test this out!

Regards,
Rajat
rajatag - 27 Aug 2006 10:21 GMT
Gordon, your solution worked well.

Thanks!
Rajat


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.