You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by bu...@apache.org on 2017/02/09 13:17:01 UTC

[Bug 60718] New: requestDestroyed not called for asynchronous after I/O error

https://bz.apache.org/bugzilla/show_bug.cgi?id=60718

            Bug ID: 60718
           Summary: requestDestroyed not called for asynchronous after I/O
                    error
           Product: Tomcat 8
           Version: 8.5.11
          Hardware: PC
            Status: NEW
          Severity: normal
          Priority: P2
         Component: Catalina
          Assignee: dev@tomcat.apache.org
          Reporter: bjkail@gmail.com
  Target Milestone: ----

Sequence of events:
1. Servlet "synchronously" writes an async response: ac = req.startAsync(); try
{ resp.getOutputStream().write(new byte[1024*1024]); } finally { ac.complete();
}
2. Client disconnects to force broken pipe (etc.): uc = new
URL("...").openConnection(); uc.getInputStream().close(); uc.disconnect();

In this case, where ServletRequestListener.requestInitialized is called. 
Summary of scenarios:
- Fail: the servlet writes the response synchronously after startAsync
(described above)
- Fail: In Tomcat 8.5.11, the servlet writes the response truly asynchronously
(with a new Thread)
- Pass: in Tomcat 8.5.6, the servlet writes the response truly asynchronously
(with a new Thread)
- Pass: the servlet writes the response truly synchronously (without
startAsync)
- Pass: the client reads the stream without disconnecting early (all Tomcat
versions, regardless of other scenarios presented).

I think requestDestroyed should always be called.

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 60718] requestDestroyed not called for asynchronous after I/O error

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=60718

--- Comment #5 from Brett Kail <bj...@gmail.com> ---
Tomcat doesn't appear to call AsyncListener for these scenarios either.

FWIW, I agree with the "in scope" interpretation.  I was expecting
requestDestroyed to be called only after the request is no longer "in scope",
not just after service returns for async.

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 60718] requestDestroyed not called for asynchronous after I/O error

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=60718

--- Comment #4 from Remy Maucherat <re...@apache.org> ---
I think it's not going to "work" unless AsyncContextImpl.fireOnComplete calls
context.fireRequestDestroyEvent(request). Or something like that.

The Tomcat code is based on the thinking that the request remains "in scope"
while the async is started (so even when the Servlet's service method is no
longer executed), which is what the spec seems to say (section 3.12).

Although it seems to contradict section 3.12 of the spec, it could be
interpreted wrong in Tomcat and requestInitialized and requestDestroyed should
simply be called around the Servlet's service method call. Right now, the code
is very careful to not call requestDestroyed if async is started, and then it's
obvious there are cases where it's not going to be called. And doing it like
that is a duplicate for what AsyncListener does so that's rather weird, but
maybe it's better for some frameworks (?). I would remove !request.isAsync() in
StandardHostValve, and drop fireRequestDestroyEvent from async dispatch.

So there is likely two possibilities, but Tomcat currently does neither.

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 60718] requestDestroyed not called for asynchronous after I/O error

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=60718

--- Comment #6 from Mark Thomas <ma...@apache.org> ---
I like the idea of moving the context.fireRequestDestroyEvent(request) call to
AsyncContextImpl.fireOnComplete(). That is much better aligned with what
section 3.12 of the spec says.

A quick test with the current Async unit tests doesn't show any failures.

Next steps are to look into the additional scenarios presented in this bug.

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 60718] requestDestroyed not called for asynchronous after I/O error

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=60718

Mark Thomas <ma...@apache.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|---                         |FIXED
             Status|NEW                         |RESOLVED

--- Comment #8 from Mark Thomas <ma...@apache.org> ---
Fixed in:
- trunk for 9.0.0.M18 onwards
- 8.5.x for 8.5.12 onwards
- 8.0.x for 8.0.42 onwards
- 7.0.x for 7.0.76 onwards

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 60718] requestDestroyed not called for asynchronous after I/O error

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=60718

--- Comment #2 from Brett Kail <bj...@gmail.com> ---
Created attachment 34742
  --> https://bz.apache.org/bugzilla/attachment.cgi?id=34742&action=edit
test project

I reviewed bug 60385 before opening this bug, and I do not think it is
relevant.  That bug is about requestInitialized throwing an exception and
therefore requestDestroyed not being called, which is reasonable.  This bug
throws no exception from requestInitialized, but it forces a client error
during getOutputStream().write().

I am attaching a test project that demonstrates the problem for me (on Windows
at least, but earlier version of the test also failed on Linux).  Install the
WAR in Tomcat, then run the main method in TestServlet.  The main method
connects to four endpoints, so I would expect four "+ requestDestroyed"
messages.  On Tomcat 8.5.6, there are only three (missing async=sync).  On
8.5.11, there is only one (missing all async scenarios).  Additionally, 8.5.11
has a noisy setErrorState stack trace (seems unnecessary?) and an
IllegalStateException from AsyncStateMachine.asyncError.

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 60718] requestDestroyed not called for asynchronous after I/O error

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=60718

Brett Kail <bj...@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEEDINFO                    |NEW

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 60718] requestDestroyed not called for asynchronous after I/O error

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=60718

--- Comment #3 from Brett Kail <bj...@gmail.com> ---
It's likely the same (or a related) problem, but access log entries are not
written for the failing cases either (ala bug 58702).

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 60718] requestDestroyed not called for asynchronous after I/O error

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=60718

Remy Maucherat <re...@apache.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |NEEDINFO
                 OS|                            |All

--- Comment #1 from Remy Maucherat <re...@apache.org> ---
Please try again stating more clearly what the code is (use an attachment), and
the supposed failure. Please also review carefully bug 60385 it seems to apply
to some of the fail scenarios described maybe (like possibly the first one).

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 60718] requestDestroyed not called for asynchronous after I/O error

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=60718

--- Comment #7 from Mark Thomas <ma...@apache.org> ---
Many thanks for the test case. I've applied a fix to trunk (9.0.x) that
addresses the issues raised by the test case. Before I back-port it, I want to
look at whether the error handling needs some refactoring.

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org