I've noticed that after upgrading from Tomcat 6.0.18 to
Tomcat 6.0.20 my comet servlet is now receiving two
EventType.END events in a row when a client disconnects.

I can duplicate with a simple test case (attached below)
and I've verified that it happens in the svn repository
under tc6.0.x/trunk as well.  I'm running on Windows XP Pro
with Sun JDK 1.6.0_15. org.apache.coyote.http11.Http11NioProtocol
enabled.

Receiving a duplicate END event isn't particularly serious (at
least in my application), but I'm seeing a more serious issue
that looks related to this problem.  It appears that after
the first END event is sent, the associated HttpResponse object
is immediately recycled and used in another request-response.
If the client of this next request starts reads the response
quickly enough, then it can encounter a read error when the
duplicate END event is processed and the request is re-closed.

Of course this secondary problem is harder to reproduce in
a small test case, but I do see it consistently in my
application.

I'm wondering if this is a legitimate bug, there's a work
around, or I'm doing something wrong.  Test case and output
are below.

-Brian


SimpleCometProcessor.java
=========================

package testcase.servlet;

import java.io.IOException;
import java.io.InputStream;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;

import org.apache.catalina.CometEvent;
import org.apache.catalina.CometProcessor;

public class SimpleCometProcessor extends HttpServlet implements CometProcessor
{
        public void event( CometEvent event ) throws IOException, 
ServletException
        {
                String eventTypeStr = event.getEventType().toString();
                String eventSubTypeStr = event.getEventSubType() == null ? 
"null" : event.getEventSubType().toString();

                System.out.println(
                        "SimpleCometProcessor.event got event " + eventTypeStr +
                        ( eventSubTypeStr == null ? "" : "/" + eventSubTypeStr 
) );

                switch ( event.getEventType() )
                {
                        case BEGIN:
                        {
                                event.setTimeout( 60 * 1000 );

                                event.getHttpServletResponse().setContentType( 
"text/plain" );
                                event.getHttpServletResponse().setHeader( 
"Cache-Control", "no-cache" );
                                event.getHttpServletResponse().setHeader( "Pragma", 
"no-cache" );
                                event.getHttpServletResponse().getOutputStream().write( 
"initial response... leaving event open".getBytes( "UTF-8" ) );
                                event.getHttpServletResponse().flushBuffer();
                                break;
                        }
                        case END:
                        {
                                event.close();
                                break;
                        }
                        case ERROR:
                        {
                                event.close();
                                break;
                        }
                        case READ:
                        {
                                InputStream is = 
event.getHttpServletRequest().getInputStream();

                                byte[] buf = new byte[ 512 ];

                                do
                                {
                                        int n = is.read( buf );

                                        System.out.println( "SimpleCometProcessor 
read returned: " + n );

                                        if ( n == -1 )
                                        {
                                                throw new IOException( "read a -1 
from inputstream" );
                                        }

                                } while ( is.available() > 0 );

                                break;
                        }
                }
        }
}


Sample Output
=============
client: (issue an HTTP GET to http://servlet/location)
server:
Sep 11, 2009 10:53:04 AM org.apache.catalina.core.AprLifecycleListener init
INFO: The APR based Apache Tomcat Native library which allows optimal 
performance in production environments was not found on the java.library.path: 
[...]
Sep 11, 2009 10:53:04 AM org.apache.tomcat.util.net.NioSelectorPool 
getSharedSelector
INFO: Using a shared selector for servlet write/read
Sep 11, 2009 10:53:04 AM org.apache.coyote.http11.Http11NioProtocol init
INFO: Initializing Coyote HTTP/1.1 on http-8080
Sep 11, 2009 10:53:04 AM org.apache.catalina.startup.Catalina load
INFO: Initialization processed in 388 ms
Sep 11, 2009 10:53:04 AM org.apache.catalina.realm.JAASRealm setContainer
INFO: Set JAAS app name Catalina
Sep 11, 2009 10:53:04 AM org.apache.catalina.core.StandardService start
INFO: Starting service Catalina
Sep 11, 2009 10:53:04 AM org.apache.catalina.core.StandardEngine start
INFO: Starting Servlet Engine: Apache Tomcat/6.0-snapshot
Sep 11, 2009 10:53:04 AM org.apache.catalina.startup.HostConfig deployDescriptor
INFO: Deploying configuration descriptor testcase.xml
Sep 11, 2009 10:53:04 AM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deploying web application directory docs
Sep 11, 2009 10:53:04 AM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deploying web application directory examples
Sep 11, 2009 10:53:04 AM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deploying web application directory host-manager
Sep 11, 2009 10:53:04 AM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deploying web application directory manager
Sep 11, 2009 10:53:04 AM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deploying web application directory ROOT
Sep 11, 2009 10:53:04 AM org.apache.coyote.http11.Http11NioProtocol start
INFO: Starting Coyote HTTP/1.1 on http-8080
Sep 11, 2009 10:53:04 AM org.apache.catalina.startup.Catalina start
INFO: Server startup in 478 ms
SimpleCometProcessor.event got event BEGIN/null

client: (interrupt the HTTP GET, such as by killing the web browser that issued 
the GET)
server:
SimpleCometProcessor.event got event END/null
SimpleCometProcessor.event got event END/null


Is the duplicate END event a bug?

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to