2010/6/11 Reich, Matthias <matthias.re...@siemens-enterprise.com>:
>
> The concept of long poll is e.g. described in
> http://www.javaworld.com/javaworld/jw-03-2008/jw-03-asynchhttp.html?page=6
>
> The sequence of events in my situation is as follows:
> - a poll request is received by the server
> - the CoyoteAdapter.service method is called and in turn
>  invokes the servlet's event method with a BEGIN event
> - request.isComet() is still true when the control returns
>  to the CoyoteAdapter.service method
> - some other thread writes a response and closes the Writer
>  of the response
> - the CoyoteAdapter.event method is called and in turn
>  invokes the servlet's event method with an END event
> - the servlet calls event.close()
> - when the control returns to the CoyoteAdapter.event method
>  we have exactly this situation:
>  response.isClosed() && !request.isComet() && status==SocketStatus.OPEN
> - thus, if the error flag is set in this situation,
>  the connection will be closed, and a new connection must be opened
>  by the browser for the subsequent poll request
>
> According to the above sequence I would expect that the connection
> is always closed if request.isComet() is still true when control
> returns to the CoyoteAdapter.service method after processing
> the BEGIN event -  no matter how long it takes from then
> until the response is written.
> Surprisingly, I did not always observe this.
>
> Anyway, if the error flag is not set in this situation,
> the connection is kept open.
>
>
>>
>> 2. The above fragment when using Comet should be equivalent to
>>
>> >    if (response.isClosed()) {
>> >        if (status==SocketStatus.OPEN) {
>> >        //CometEvent.close was called during an event.
>> >        request.getEvent().setEventType(CometEvent.EventType.END);
>> >        request.getEvent().setEventSubType(null);
>> >
>> > // don't set the error flag here - otherwise the connection
>> will be closed
>> > // whenever a long poll is answered already during event handling:
>> >        // error = true;
>> >
>>
>> Response#isClosed():
>>     public boolean isClosed() {
>>         return outputBuffer.isClosed();
>>     }
>
> No, it is not equivalent: response.isClosed() is true after closing
> the Writer or OutputStream, whereas request.isComet() is true
> until event.close() is called.
>
>>
>> If you will not be able to send your answer, why not to close the
>> socket right away?
>
> I was able to send the answer and would like to use the connection
> also for the next poll request. (or for some other request
> the browser decides to send through this connection)
>
>>
>> 3. It would be much more readable, if you provided your changes in the
>> unified diff format. (even better if it were generated with "svn diff"
>> command against sources retrieved from svn).
>>
>
> --- 
> C:\DOCUME~1\rm041693\LOCALS~1\Temp\CoyoteAdapter.java-revBASE.svn001.tmp.java 
>       Do Jun 10 22:22:20 2010
> +++ 
> D:\tomcat\TOMCAT_6_0_26\java\org\apache\catalina\connector\CoyoteAdapter.java 
>       Mo Jun  7 17:30:23 2010
> @@ -215,7 +215,9 @@
>                         //CometEvent.close was called during an event.
>                         
> request.getEvent().setEventType(CometEvent.EventType.END);
>                         request.getEvent().setEventSubType(null);
> -                        error = true;
> +                        // don't set the error flag - otherwise the socket 
> will be closed
> +                        // whenever CometEvent.close is called during the 
> event
> +                        // error = true;
>                         
> connector.getContainer().getPipeline().getFirst().event(request, response, 
> request.getEvent());
>                     }
>                     res.action(ActionCode.ACTION_COMET_END, null);
>

Now I understand. Thank you.

I would say that you are trying to combine Comet and Keep-Alive.

In comet to send a portion of data (a response), you do
writer.flush(). It sends the data over the wire. Doing event.close()
terminates comet request processing.

If it were possible not to close the connection, it were possible to
alternate comet and non-comet processing of subsequent requests over
the same connection, and to process different requests by different
servlets.

> - some other thread writes a response and closes the Writer
>  of the response

Response object is not thread safe. You must write your response in
the thread that received your EventType.READ event (or any other
event) while you are processing that event.

Otherwise, any random result might happen.


BTW, for reference:
There exists the following documentation page,
http://tomcat.apache.org/tomcat-6.0-doc/aio.html#CometEvent
and sample code in
webapps/examples/WEB-INF/classes/chat/ChatServlet.java
plus some helper JSPs.

The sample is callable as
http://localost:8080/examples/jsp/chat/chat.jsp  in Tomcat 6.0.26 and earlier
http://localost:8080/examples/jsp/chat/index.jsp  in Tomcat 7 and in
Tomcat 6.0.27 and later


Regarding Comet + Keep-Alive, if it does not work, it is worth filing
an enhancement request against Tomcat 7.   It would be easier if there
were some sample code or better a test case.  This new use case has to
be tested.

The patch you proposing looks promising, but as of now I am not sure that

a) both cases when that branch is called are equivalent,
I mean (response.isClosed()) vs. (!request.isComet()) whether in both
cases we can go without closing the socket
Calling CometEventImpl.close() will set both conditions to true.
I think that response.isClosed() when isComet() == true will mean an
error and needs closing the socket. Need to think more about it.

b) how the socket will be processed further and be returned to the
poller. There are non-comet vs. comet pollers. There are some
keepAlive settings (like "maxKeepAliveRequests") and those have to be
respected.


Best regards,
Konstantin Kolinko

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

Reply via email to