[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
Re: [servlet-dev] Non-blocking IO and ServletOutputStream.close()
|
On 09/01/2023 09:04, Mark Thomas wrote:
On 07/01/2023 06:57, Greg Wilkins wrote:
Mark,
Conceptually both close and complete could be thought of as write
operations that need to wait until a true isReady() return before
being called.
However, unlike a write operation, they cannot carry additional data
to be queued, nor be called multiple times, so there is no unbounded
data commitment if we let them be called whilst a write completion is
still pending. In this interpretation, they are state changes rather
than writes.
So since the spec has never said otherwise, i think we must use the
second interpretation.
Thanks for the review Greg. There is a comment in the Tomcat code to the
effect that complete()/dispatch() are not allowed while async IO is in
progress. I need to do some research to see if I can find where that
comment originated as that point is rather fundamental to this discussion.
The comment in the Tomcat code is [1]. It was added by Filip when he
wrote the original test [2]. That is consistent with when the Servlet
3.1 API was being discussed as part of JSR 340.
I went back through the JSR 340 EG discussions to see if I could find
anything that could have led to Filip adding that comment.
The initial draft for async IO included a write() followed immediately
by a complete() [3].
When I asked what looks like the same question almost a decade ago, the
consensus was that calling write() or complete() with a write in
progress should trigger an exception [4].
The topic was raised again in Servlet 4.0 / JSR 369 [5] and the
conclusion was the same - calling complete() with a write in progress
should trigger an exception.
I haven't found any further discussions since until this one.
I don't think any of the conclusions from those discussions made it into
the spec document or the Javadoc.
The TCK includes a test that calls complete() without isReady()
returning true [6] and a test that calls write(), flush() and complete()
in sequence [7].
I am unable to explain why the behavior expected by the TCK is the exact
opposite of what was agreed multiple times by the EG. I will note that
the EG at the time, unlike now, had no access to the TCK source nor any
ability to update the spec document or Javadoc.
Given the behavior expected by the TCK, I don't think we have any choice
but to allow close(), complete() and dispatch() while async read/writes
are in progress.
I'll leave this thread for a couple of days in case anyone has any
further comments. Assuming no further discussion is required, I'll open
an issue and provide a PR to update the Javadoc and spec document
towards the end of this week / beginning of next.
Mark
[1]
https://github.com/apache/tomcat/blame/main/test/org/apache/catalina/nonblocking/TestNonBlockingAPI.java#L823
[2]
https://github.com/apache/tomcat/commit/690eb5c8d25d0fe26835386057bd455257cbdb86
[3]
https://download.oracle.com/javaee-archive/servlet-spec.java.net/jsr340-experts/2011/09/0056.html
[4]
https://download.oracle.com/javaee-archive/servlet-spec.java.net/jsr340-experts/2013/04/0569.html
[5]
https://download.oracle.com/javaee-archive/servlet-spec.java.net/jsr369-experts/2015/11/0312.html
[6]
https://github.com/jakartaee/platform-tck/blob/master/src/com/sun/ts/tests/servlet/api/jakarta_servlet_http/writelistener/TestListener.java
[7]
https://github.com/jakartaee/platform-tck/blob/master/src/com/sun/ts/tests/servlet/spec/async/TestServlet.java#L45