tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From André Warnier>
Subject Re: AsyncListener.onError and disconnected client
Date Thu, 25 Apr 2013 13:11:24 GMT
Mark Thomas wrote:
> On 25/04/2013 13:20, Rossen Stoyanchev wrote:
>> ----- Original Message -----
>>> From: "Mark Thomas" <>
>>> To: "Tomcat Users List" <>
>>> Sent: Wednesday, April 24, 2013 2:14:53 PM
>>> Subject: Re: AsyncListener.onError and disconnected client
>>> On 24/04/2013 18:38, Rossen Stoyanchev wrote:
>>>> ----- Original Message -----
>>>>> From: "Mark Thomas" <>
>>>>> To: "Tomcat Users List" <>
>>>>> Sent: Wednesday, April 24, 2013 12:47:54 PM
>>>>> Subject: Re: AsyncListener.onError and disconnected client
>>>>> On 24/04/2013 16:33, Rossen Stoyanchev wrote:
>>>>>> Hi,
>>>>>> I've seen various discussions here and on the web but I haven't
>>>>>> found
>>>>>> a conclusive answer. Why does an AsyncListener not receive
>>>>>> onError
>>>>>> notifications when a client disconnects?
>>>>> Because the Servlet EG says that is the required behaviour. The EG
>>>>> is
>>>>> currently revisiting that decision. See
>>>> Thanks for that reference. Is there something in the spec that
>>>> explicitly makes requires this?
>>> Not that I am aware of which why I said "EG" rather than
>>> "specification".
>>>> The JIRA ticket is about adding a "disconnect" callback but I can
>>>> imagine in the very least, onComplete can be called. After the
>>>> connection is over.
>>> onComplete should be called once the connection times out.
>> My understanding is that onComplete is always called regardless of how the async
request completed, i.e. following onTimeout, or onError. I would expect it to be called after
a client disconnect as well for consistency. Also I wonder if a disconnect method is even
needed? The onError method could be called indicating that the "asynchronous operation has
failed to complete" (from the Javadoc). That's actually what I expected when I first tried.
> It is. The issue is when is happens.
> The issue is that there is no event (I am aware of) that the container
> can monitor.
> BIO - Only know once a read/write fails.
> NIO - A current read/write will fail.
>       The socket can be explicitly tested (but isn't currently)
>       If the socket is in the poller I'd expect an error event
>       If the socket was added to the poller I'd expect an error event
> APR - A current read/write will fail.
>       If the socket is in the poller I'd expect an error event
>       If the socket was added to the poller I'd expect an error event
>       It might be possible to test the socket but I haven't checked
> There are times when a socket is not being used for read/write and is
> not in a poller (e.g. when the app is doing some processing that doesn't
> require output to the user agent). You won't get a notification of
> disconnect in this case until the app has finished.
> I wonder (for NIO and APR) if you could always have the socket in the
> poller in order to detect a disconnect? You'd need to carefully keep
> track of the registered interests for the socket and there are likely to
> be threading issues as (currently) the Servlet spec is written on the
> basis that there is only every one thread processing a socket at a time
> (Tomcat's WebSocket impl violates that assumption - that is the subject
> of another discussion).
>>>>>> To my knowledge there is nothing inherent in NIO and TCP that
>>>>>> prevents the server from detecting that the client has
>>>>>> disconnected.
>>>>>> The WebSocket implementation detects disconnected clients
>>>>>> immediately
>>>>>> and other HTTP servers (e.g. node) seem to be able to do this.
>>>>>> What
>>>>>> is it about the Servlet async support that prevents it from
>>>>>> knowing
>>>>>> when a client has disconnected?
>>>>> It would mean having to ditch the BIO connector / or not being
>>>>> able
>>>>> to pass the TCK (assuming the TCK tested this) when using the BIO
>>>>> connector.
>>>> I guess this goes back to the previous question about whether there
>>>> is an explicit requirement and therefore test. Why would a TCK
>>>> test explicitly check that disconnects are not communicated to
>>>> AsyncListeners? Or is it a more indirect consequence of some other
>>>> requirement?
>>> My point was that if a disconnect event was added to the spec then
>>> the BIO connector could never be spec compliant.
>> If I understand correctly, you're saying the BIO connector can not detect a client
> It can't until you try and read or write from the socket.
>>> On reflection, it might not be that bad. The event could be fired
>>> just not when the client disconnects. It would have to wait until an
>>> attempt was made to read from / write to the socket.
>> That's actually not very different from the current situation where I catch any exceptions
while trying to write to the response and then call asyncContext.complete(). I suppose it
would make it more clear that a client has disconnected (as opposed to some other error),
but once writing to the response has raised an error, it doesn't make a big difference what
the error is.
> This really comes down to how the spec has been written. onError is for
> errors that happen in the container during dispatch (i.e. at the end of
> the async phase) that the app does not have visibility of. It allows the
> container to tell the app that the request did not complete normally. It
> is not intended for IO errors that happen during the async phase which
> the app can just catch.

Sorry to butt in, but the issue interests me in another context.
My question : is there any kind of I/O operation that a servlet could do to the response 
stream (even in-between two real "data" I/O) which would be guaranteed to return an error

if the client has closed the connection in the meantime, no matter which Connector 
implementation underlies it ?
It would have to be something which does not really send any real data byte, so as not to

corrupt a response that may be partially under way.  Some kind of "ping", to say it otherwise.

To unsubscribe, e-mail:
For additional commands, e-mail:

View raw message