You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Sebastiaan van Erk <se...@sebster.com> on 2007/05/04 09:20:16 UTC

comet: async close exceptions

Hi,

Due to the latest changes (r535030) to the Comet code I'm getting the 
AsyncCloseExceptions again, meaning that my synchronization which worked 
before is not correct anymore.

What I am doing is synchronizing all access to the response output 
stream and synchronizing with the same lock around event.close() in the 
event() method.

This is the stack trace I get in my async application code.

Caused by: java.nio.channels.AsynchronousCloseException
        at 
java.nio.channels.spi.AbstractInterruptibleChannel.end(AbstractInterruptibleChannel.java:185)
        at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:341)
        at org.apache.tomcat.util.net.NioChannel.write(NioChannel.java:111)
        at 
org.apache.tomcat.util.net.NioBlockingSelector.write(NioBlockingSelector.java:57)
        at 
org.apache.tomcat.util.net.NioSelectorPool.write(NioSelectorPool.java:135)
        at 
org.apache.tomcat.util.net.NioSelectorPool.write(NioSelectorPool.java:130)
        at 
org.apache.coyote.http11.InternalNioOutputBuffer.writeToSocket(InternalNioOutputBuffer.java:433)
        at 
org.apache.coyote.http11.InternalNioOutputBuffer.flushBuffer(InternalNioOutputBuffer.java:761)
        at 
org.apache.coyote.http11.InternalNioOutputBuffer.flush(InternalNioOutputBuffer.java:310)
        at 
org.apache.coyote.http11.Http11NioProcessor.action(Http11NioProcessor.java:1061)
        at org.apache.coyote.Response.action(Response.java:183)
        at 
org.apache.catalina.connector.OutputBuffer.doFlush(OutputBuffer.java:314)
        at 
org.apache.catalina.connector.OutputBuffer.flush(OutputBuffer.java:288)
        at 
org.apache.catalina.connector.CoyoteOutputStream.flush(CoyoteOutputStream.java:98)
        at 
com.sebster.comet.util.io.NoCloseOutputStream.flush(NoCloseOutputStream.java:36)
        at 
com.sebster.comet.util.io.AutoFlushingOutputStream.write(AutoFlushingOutputStream.java:31)
        at 
com.sebster.comet.util.io.SynchronizedOutputStream.write(SynchronizedOutputStream.java:29)

My application code writes a single byte to the response output stream 
and flushes it (the AutoFlushingOutputStream), which causes my client to 
close the socket. It seems that as a result of my client closing the 
socket, the output stream is closed on the Tomcat side as well, before 
my (synchronized) write finishes. This must happen outside of 
event.close() since I'm synchronizing around that as well. (BTW: the 
NoCloseOutputStream makes sure that a close() call in my async 
application code is not sent to the underlying output stream, and for 
the rest it just delegates).

What is the correct way to synchronize this in the new situation?

Regards,
Sebastiaan

---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: comet: async close exceptions

Posted by Sebastiaan van Erk <se...@sebster.com>.
Hi,

I seemed to have forgotten to synchronize a single event.close() which 
triggered the problem (but only after yesterday's changes). It is 
actually working again now...

Regards,
Sebastiaan

Sebastiaan van Erk wrote:
> Filip Hanik - Dev Lists wrote:
>> Filip Hanik - Dev Lists wrote:
>>> Sebastiaan van Erk wrote:
>>>> Hi,
>>>>
>>>> Due to the latest changes (r535030) to the Comet code I'm getting 
>>>> the AsyncCloseExceptions again, meaning that my synchronization 
>>>> which worked before is not correct anymore.
>>>>
>>>> What I am doing is synchronizing all access to the response output 
>>>> stream and synchronizing with the same lock around event.close() in 
>>>> the event() method.
>>>>
>>>> This is the stack trace I get in my async application code.
>>>>
>>>> Caused by: java.nio.channels.AsynchronousCloseException
>>>>        at 
>>>> java.nio.channels.spi.AbstractInterruptibleChannel.end(AbstractInterruptibleChannel.java:185) 
>>>>
>>>>        at 
>>>> sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:341)
>>>>        at 
>>>> org.apache.tomcat.util.net.NioChannel.write(NioChannel.java:111)
>>>>        at 
>>>> org.apache.tomcat.util.net.NioBlockingSelector.write(NioBlockingSelector.java:57) 
>>>>
>>>>        at 
>>>> org.apache.tomcat.util.net.NioSelectorPool.write(NioSelectorPool.java:135) 
>>>>
>>>>        at 
>>>> org.apache.tomcat.util.net.NioSelectorPool.write(NioSelectorPool.java:130) 
>>>>
>>>>        at 
>>>> org.apache.coyote.http11.InternalNioOutputBuffer.writeToSocket(InternalNioOutputBuffer.java:433) 
>>>>
>>>>        at 
>>>> org.apache.coyote.http11.InternalNioOutputBuffer.flushBuffer(InternalNioOutputBuffer.java:761) 
>>>>
>>>>        at 
>>>> org.apache.coyote.http11.InternalNioOutputBuffer.flush(InternalNioOutputBuffer.java:310) 
>>>>
>>>>        at 
>>>> org.apache.coyote.http11.Http11NioProcessor.action(Http11NioProcessor.java:1061) 
>>>>
>>>>        at org.apache.coyote.Response.action(Response.java:183)
>>>>        at 
>>>> org.apache.catalina.connector.OutputBuffer.doFlush(OutputBuffer.java:314) 
>>>>
>>>>        at 
>>>> org.apache.catalina.connector.OutputBuffer.flush(OutputBuffer.java:288) 
>>>>
>>>>        at 
>>>> org.apache.catalina.connector.CoyoteOutputStream.flush(CoyoteOutputStream.java:98) 
>>>>
>>>>        at 
>>>> com.sebster.comet.util.io.NoCloseOutputStream.flush(NoCloseOutputStream.java:36) 
>>>>
>>>>        at 
>>>> com.sebster.comet.util.io.AutoFlushingOutputStream.write(AutoFlushingOutputStream.java:31) 
>>>>
>>>>        at 
>>>> com.sebster.comet.util.io.SynchronizedOutputStream.write(SynchronizedOutputStream.java:29) 
>>>>
>>>>
>>>> My application code writes a single byte to the response output 
>>>> stream and flushes it (the AutoFlushingOutputStream), which causes 
>>>> my client to close the socket. It seems that as a result of my 
>>>> client closing the socket, the output stream is closed on the 
>>>> Tomcat side as well, before my (synchronized) write finishes. This 
>>>> must happen outside of event.close() since I'm synchronizing around 
>>>> that as well. (BTW: the NoCloseOutputStream makes sure that a 
>>>> close() call in my async application code is not sent to the 
>>>> underlying output stream, and for the rest it just delegates).
>>>>
>>>> What is the correct way to synchronize this in the new situation?
>>> This is because when an event happens, CoyoteAdapter will now check 
>>> the channel by doing a read(in order for available to work). This 
>>> will close the underlying connection, and you'll get this error.
>>> This is not something you can synchronize on, essentially, you need 
>>> to catch the exception instead, as no matter what goes on, if the 
>>> client closes the connection, you can't expect the next write to work.
>> what I meant, "this is something you *can't* synchronize on"
>
> Are there plans to make Comet immediately close the socket if the 
> response is closed server side and the "Connection: close" header is 
> set? Or is the "notify" method on the event which you guys are 
> discussing on the dev list intended to handle the async close case?
>
> Currently this is the workaround for the async close problem, and it's 
> getting a bit messy now I guess:
> 1) write last content byte asynchronously on the server
> 2) have the client shut down the connection (instead of reading until 
> -1), since it got content-length bytes
> 3) async application code gets AsyncCloseException in above (1) write 
> call
> 4) ignore AsyncCloseException?
> 5) I don't seem to get any more events for this request (END, or 
> ERROR); does this mean I have to do the cleanup from the async 
> application code?
>>>
>>> Filip
>>>
> Regards,
> Sebastiaan
>
> ---------------------------------------------------------------------
> To start a new topic, e-mail: users@tomcat.apache.org
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
>

---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: comet: async close exceptions

Posted by Sebastiaan van Erk <se...@sebster.com>.
Filip Hanik - Dev Lists wrote:
> Filip Hanik - Dev Lists wrote:
>> Sebastiaan van Erk wrote:
>>> Hi,
>>>
>>> Due to the latest changes (r535030) to the Comet code I'm getting 
>>> the AsyncCloseExceptions again, meaning that my synchronization 
>>> which worked before is not correct anymore.
>>>
>>> What I am doing is synchronizing all access to the response output 
>>> stream and synchronizing with the same lock around event.close() in 
>>> the event() method.
>>>
>>> This is the stack trace I get in my async application code.
>>>
>>> Caused by: java.nio.channels.AsynchronousCloseException
>>>        at 
>>> java.nio.channels.spi.AbstractInterruptibleChannel.end(AbstractInterruptibleChannel.java:185) 
>>>
>>>        at 
>>> sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:341)
>>>        at 
>>> org.apache.tomcat.util.net.NioChannel.write(NioChannel.java:111)
>>>        at 
>>> org.apache.tomcat.util.net.NioBlockingSelector.write(NioBlockingSelector.java:57) 
>>>
>>>        at 
>>> org.apache.tomcat.util.net.NioSelectorPool.write(NioSelectorPool.java:135) 
>>>
>>>        at 
>>> org.apache.tomcat.util.net.NioSelectorPool.write(NioSelectorPool.java:130) 
>>>
>>>        at 
>>> org.apache.coyote.http11.InternalNioOutputBuffer.writeToSocket(InternalNioOutputBuffer.java:433) 
>>>
>>>        at 
>>> org.apache.coyote.http11.InternalNioOutputBuffer.flushBuffer(InternalNioOutputBuffer.java:761) 
>>>
>>>        at 
>>> org.apache.coyote.http11.InternalNioOutputBuffer.flush(InternalNioOutputBuffer.java:310) 
>>>
>>>        at 
>>> org.apache.coyote.http11.Http11NioProcessor.action(Http11NioProcessor.java:1061) 
>>>
>>>        at org.apache.coyote.Response.action(Response.java:183)
>>>        at 
>>> org.apache.catalina.connector.OutputBuffer.doFlush(OutputBuffer.java:314) 
>>>
>>>        at 
>>> org.apache.catalina.connector.OutputBuffer.flush(OutputBuffer.java:288)
>>>        at 
>>> org.apache.catalina.connector.CoyoteOutputStream.flush(CoyoteOutputStream.java:98) 
>>>
>>>        at 
>>> com.sebster.comet.util.io.NoCloseOutputStream.flush(NoCloseOutputStream.java:36) 
>>>
>>>        at 
>>> com.sebster.comet.util.io.AutoFlushingOutputStream.write(AutoFlushingOutputStream.java:31) 
>>>
>>>        at 
>>> com.sebster.comet.util.io.SynchronizedOutputStream.write(SynchronizedOutputStream.java:29) 
>>>
>>>
>>> My application code writes a single byte to the response output 
>>> stream and flushes it (the AutoFlushingOutputStream), which causes 
>>> my client to close the socket. It seems that as a result of my 
>>> client closing the socket, the output stream is closed on the Tomcat 
>>> side as well, before my (synchronized) write finishes. This must 
>>> happen outside of event.close() since I'm synchronizing around that 
>>> as well. (BTW: the NoCloseOutputStream makes sure that a close() 
>>> call in my async application code is not sent to the underlying 
>>> output stream, and for the rest it just delegates).
>>>
>>> What is the correct way to synchronize this in the new situation?
>> This is because when an event happens, CoyoteAdapter will now check 
>> the channel by doing a read(in order for available to work). This 
>> will close the underlying connection, and you'll get this error.
>> This is not something you can synchronize on, essentially, you need 
>> to catch the exception instead, as no matter what goes on, if the 
>> client closes the connection, you can't expect the next write to work.
> what I meant, "this is something you *can't* synchronize on"

Are there plans to make Comet immediately close the socket if the 
response is closed server side and the "Connection: close" header is 
set? Or is the "notify" method on the event which you guys are 
discussing on the dev list intended to handle the async close case?

Currently this is the workaround for the async close problem, and it's 
getting a bit messy now I guess:
1) write last content byte asynchronously on the server
2) have the client shut down the connection (instead of reading until 
-1), since it got content-length bytes
3) async application code gets AsyncCloseException in above (1) write call
4) ignore AsyncCloseException?
5) I don't seem to get any more events for this request (END, or ERROR); 
does this mean I have to do the cleanup from the async application code?
>>
>> Filip
>>
Regards,
Sebastiaan

---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: comet: async close exceptions

Posted by Filip Hanik - Dev Lists <de...@hanik.com>.
Filip Hanik - Dev Lists wrote:
> Sebastiaan van Erk wrote:
>> Hi,
>>
>> Due to the latest changes (r535030) to the Comet code I'm getting the 
>> AsyncCloseExceptions again, meaning that my synchronization which 
>> worked before is not correct anymore.
>>
>> What I am doing is synchronizing all access to the response output 
>> stream and synchronizing with the same lock around event.close() in 
>> the event() method.
>>
>> This is the stack trace I get in my async application code.
>>
>> Caused by: java.nio.channels.AsynchronousCloseException
>>        at 
>> java.nio.channels.spi.AbstractInterruptibleChannel.end(AbstractInterruptibleChannel.java:185) 
>>
>>        at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:341)
>>        at 
>> org.apache.tomcat.util.net.NioChannel.write(NioChannel.java:111)
>>        at 
>> org.apache.tomcat.util.net.NioBlockingSelector.write(NioBlockingSelector.java:57) 
>>
>>        at 
>> org.apache.tomcat.util.net.NioSelectorPool.write(NioSelectorPool.java:135) 
>>
>>        at 
>> org.apache.tomcat.util.net.NioSelectorPool.write(NioSelectorPool.java:130) 
>>
>>        at 
>> org.apache.coyote.http11.InternalNioOutputBuffer.writeToSocket(InternalNioOutputBuffer.java:433) 
>>
>>        at 
>> org.apache.coyote.http11.InternalNioOutputBuffer.flushBuffer(InternalNioOutputBuffer.java:761) 
>>
>>        at 
>> org.apache.coyote.http11.InternalNioOutputBuffer.flush(InternalNioOutputBuffer.java:310) 
>>
>>        at 
>> org.apache.coyote.http11.Http11NioProcessor.action(Http11NioProcessor.java:1061) 
>>
>>        at org.apache.coyote.Response.action(Response.java:183)
>>        at 
>> org.apache.catalina.connector.OutputBuffer.doFlush(OutputBuffer.java:314) 
>>
>>        at 
>> org.apache.catalina.connector.OutputBuffer.flush(OutputBuffer.java:288)
>>        at 
>> org.apache.catalina.connector.CoyoteOutputStream.flush(CoyoteOutputStream.java:98) 
>>
>>        at 
>> com.sebster.comet.util.io.NoCloseOutputStream.flush(NoCloseOutputStream.java:36) 
>>
>>        at 
>> com.sebster.comet.util.io.AutoFlushingOutputStream.write(AutoFlushingOutputStream.java:31) 
>>
>>        at 
>> com.sebster.comet.util.io.SynchronizedOutputStream.write(SynchronizedOutputStream.java:29) 
>>
>>
>> My application code writes a single byte to the response output 
>> stream and flushes it (the AutoFlushingOutputStream), which causes my 
>> client to close the socket. It seems that as a result of my client 
>> closing the socket, the output stream is closed on the Tomcat side as 
>> well, before my (synchronized) write finishes. This must happen 
>> outside of event.close() since I'm synchronizing around that as well. 
>> (BTW: the NoCloseOutputStream makes sure that a close() call in my 
>> async application code is not sent to the underlying output stream, 
>> and for the rest it just delegates).
>>
>> What is the correct way to synchronize this in the new situation?
> This is because when an event happens, CoyoteAdapter will now check 
> the channel by doing a read(in order for available to work). This will 
> close the underlying connection, and you'll get this error.
> This is not something you can synchronize on, essentially, you need to 
> catch the exception instead, as no matter what goes on, if the client 
> closes the connection, you can't expect the next write to work.
what I meant, "this is something you *can't* synchronize on"
>
> Filip
>>
>> Regards,
>> Sebastiaan
>>
>> ---------------------------------------------------------------------
>> To start a new topic, e-mail: users@tomcat.apache.org
>> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
>> For additional commands, e-mail: users-help@tomcat.apache.org
>>
>>
>>
>
>
> ---------------------------------------------------------------------
> To start a new topic, e-mail: users@tomcat.apache.org
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
>
>
>


---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: comet: async close exceptions

Posted by Filip Hanik - Dev Lists <de...@hanik.com>.
Sebastiaan van Erk wrote:
> Hi,
>
> Due to the latest changes (r535030) to the Comet code I'm getting the 
> AsyncCloseExceptions again, meaning that my synchronization which 
> worked before is not correct anymore.
>
> What I am doing is synchronizing all access to the response output 
> stream and synchronizing with the same lock around event.close() in 
> the event() method.
>
> This is the stack trace I get in my async application code.
>
> Caused by: java.nio.channels.AsynchronousCloseException
>        at 
> java.nio.channels.spi.AbstractInterruptibleChannel.end(AbstractInterruptibleChannel.java:185) 
>
>        at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:341)
>        at 
> org.apache.tomcat.util.net.NioChannel.write(NioChannel.java:111)
>        at 
> org.apache.tomcat.util.net.NioBlockingSelector.write(NioBlockingSelector.java:57) 
>
>        at 
> org.apache.tomcat.util.net.NioSelectorPool.write(NioSelectorPool.java:135) 
>
>        at 
> org.apache.tomcat.util.net.NioSelectorPool.write(NioSelectorPool.java:130) 
>
>        at 
> org.apache.coyote.http11.InternalNioOutputBuffer.writeToSocket(InternalNioOutputBuffer.java:433) 
>
>        at 
> org.apache.coyote.http11.InternalNioOutputBuffer.flushBuffer(InternalNioOutputBuffer.java:761) 
>
>        at 
> org.apache.coyote.http11.InternalNioOutputBuffer.flush(InternalNioOutputBuffer.java:310) 
>
>        at 
> org.apache.coyote.http11.Http11NioProcessor.action(Http11NioProcessor.java:1061) 
>
>        at org.apache.coyote.Response.action(Response.java:183)
>        at 
> org.apache.catalina.connector.OutputBuffer.doFlush(OutputBuffer.java:314)
>        at 
> org.apache.catalina.connector.OutputBuffer.flush(OutputBuffer.java:288)
>        at 
> org.apache.catalina.connector.CoyoteOutputStream.flush(CoyoteOutputStream.java:98) 
>
>        at 
> com.sebster.comet.util.io.NoCloseOutputStream.flush(NoCloseOutputStream.java:36) 
>
>        at 
> com.sebster.comet.util.io.AutoFlushingOutputStream.write(AutoFlushingOutputStream.java:31) 
>
>        at 
> com.sebster.comet.util.io.SynchronizedOutputStream.write(SynchronizedOutputStream.java:29) 
>
>
> My application code writes a single byte to the response output stream 
> and flushes it (the AutoFlushingOutputStream), which causes my client 
> to close the socket. It seems that as a result of my client closing 
> the socket, the output stream is closed on the Tomcat side as well, 
> before my (synchronized) write finishes. This must happen outside of 
> event.close() since I'm synchronizing around that as well. (BTW: the 
> NoCloseOutputStream makes sure that a close() call in my async 
> application code is not sent to the underlying output stream, and for 
> the rest it just delegates).
>
> What is the correct way to synchronize this in the new situation?
This is because when an event happens, CoyoteAdapter will now check the 
channel by doing a read(in order for available to work). This will close 
the underlying connection, and you'll get this error.
This is not something you can synchronize on, essentially, you need to 
catch the exception instead, as no matter what goes on, if the client 
closes the connection, you can't expect the next write to work.

Filip
>
> Regards,
> Sebastiaan
>
> ---------------------------------------------------------------------
> To start a new topic, e-mail: users@tomcat.apache.org
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
>
>
>


---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org