users@glassfish.java.net

Glassfish 3.0.1 Comet 100% CPU issue

From: <glassfish_at_javadesktop.org>
Date: Wed, 11 Aug 2010 16:36:55 PDT

[b]Question 1[/b]
I have no doubt that the issue is related to my poor understanding of Comet and the way that I'm using it. Hopefully someone can spot the defect.

Setup:
 - Glassfish 3.0.1 OSS (with all up to date patches, etc..) running locally on my windows development box
 - Clients are HTTPClient 4.0 based applications connecting over HTTP

Problem:
After a timeout or a client close (not really sure at which time it breaks), the comet processor (or Grizzly's implementation of it) seems to spin out of control continually running through:

[code]CometEngine.interrupt(CometTask, boolean) line: 395
CometTask.checkIfClientClosedConnection(SelectionKey) line: 197
CometTask.handleSelectedKey(SelectionKey) line: 178
SelectorHandlerRunner.handleSelectedKey(SelectionKey, SelectorHandler, NIOContext) line: 274
SelectorHandlerRunner.handleSelectedKeys(Set<SelectionKey>, SelectorHandler, NIOContext) line: 258
SelectorHandlerRunner.doSelect(SelectorHandler, NIOContext) line: 195
SelectorHandlerRunner.run() line: 130
ThreadPoolExecutor$Worker.runTask(Runnable) line: 886
ThreadPoolExecutor$Worker.run() line: 908
WorkerThreadImpl(Thread).run() line: 619 [/code]

The following line seems to returns false when it spins forever:
   [code]if (task != null && task.getCometContext().handlers().remove(task.cometHandler) != null)[/code]

There are no handlers within the comet context (I remove the handler from the context on either interrupt or terminate more or less the way the grizzly example was from http://docs.sun.com/app/docs/doc/820-4496/ghgxk?a=view.


[b]Question 2[/b]
As a side note, there was one more strange behavior I had to work around when initially developing my comet. When the notify is triggered, it happens on the system's created comet threads which I suppose are on different class loaders from my application's code context sitting in an EAR->WAR. When processing the notification, I have to set the thread's classloader to my context and then back again like follows:

[code]ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
      try
      {
         Thread.currentThread().setContextClassLoader(
               OneWarFileClass.class.getClassLoader());

        ... DO MY WORK HERE...
      finally
      {
         Thread.currentThread().setContextClassLoader(oldCl);
      }
[/code]

I don't have a problem with it, but I was wondering if this was all strictly necessary, or if there was a more elegant solution to this workaround.
[Message sent by forum member 'dchemko']

http://forums.java.net/jive/thread.jspa?messageID=479931