Hi,

I have been battling with the comet event handling for a few weeks. The main
symptom is that the CPU usages may go high (60%), especially from a Firefox
connection. My page flow looks like:
- start firefox
- go to a login page to start a http session
- go to a page with comet subscription, see the comet events flowing
- go to the logout page which does a session.invalidate() and redirect back
to the page
- visit any page of this webapp, the CPU goes way up.

I have done a number of things trying to fix that, including:
- upgrade to JDK 1.6u16 (as there is a mention of socket select bug fixed in
1.6u4 on Windows)
- try both NIO connector and APR (as suggested in one forum comment)
- try to wrap the output stream in a synchronized stream and check for
stream closing.
- flush the output stream before closing (but that always resulting in NPE)

None of these works.

The CPU thread dump shows that it is spinning at either
NioEndPoint$Poller.run() or ArpendPoint$Poller.run() of the comet polling
thread. (In fact, if I suspend the thread in debugger, the CPU usages return
to 0.)

The problem could be triggered in IE as well but much less frequently, so
not sure how to reproduce.

What else I should be looking for?

Thanks
-----
My event() handler looks like

        if (event.getEventType() == CometEvent.EventType.BEGIN) {
            log.info("Begin comet channel session:", httpSession.getId());
            response.flushBuffer();
            s_connections.put(httpSession.getId(), response);
        } else if (event.getEventType() == CometEvent.EventType.ERROR) {
            final EventSubType subtype = event.getEventSubType();
            if (subtype == CometEvent.EventSubType.TIMEOUT) {
                log.info("ignore timeout");
            } else if (subtype == CometEvent.EventSubType.CLIENT_DISCONNECT)
{
                closeSessionConnection(httpSession.getId(), false);
                event.close();
            }
        } else if (event.getEventType() == CometEvent.EventType.END) {
            final EventSubType subtype = event.getEventSubType();
            if (subtype == null || subtype ==
CometEvent.EventSubType.SESSION_END) {
                // ... unsubscribe all comet topics ...
            }
            closeSessionConnection(session);
            event.close();
        } else if (event.getEventType() == CometEvent.EventType.READ) {
            InputStream is = request.getInputStream();
            byte[] buf = new byte[512];
            do {
                int n = is.read(buf); // can throw an IOException
                if (n > 0) {
                } else if (n < 0) {
                    closeSessionConnection(httpSession.getId());
                    event.close();
                    return;
                }
            } while (is.available() > 0);
        }
    protected static void closeSessionConnection(String sessionId) throws
IOException {
        HttpServletResponse response = s_connections.remove(sessionId);
        if (response == null) {
            return;
        }
        synchronized (response) {
                PrintWriter writer = response.getWriter();
                try {
                    response.flushBuffer();
                    log.info("Http response flushed");
                } catch (NullPointerException e) { // always happen
                } catch (Exception e) {
                    log.error("Error flushing response", e);
                }
                try {
                    writer.close();
                } catch (NullPointerException e) { // always happen
                } catch (Exception e) {
                    log.error("Error closing writer", e);
                }
        }
    }
the JavaScript codes (for FF) basically looks like

function cometStart(url) {
      var xmlhttp = new XMLHttpRequest();
      xmlhttp.onreadystatechange = function() {

         if(xmlhttp.readyState == 4 && cometSettings.active) {
            cometStart(url);
            return(false);
         }

         if(xmlhttp.readyState == 3) {
            var data = xmlhttp.responseText;
            // process data
         }
      };
      xmlhttp.open('GET', url, true);
      xmlhttp.send(null);
      cometSettings.active = true;
}

Reply via email to