[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
Re: [servlet-dev] Non-blocking IO and ServletOutputStream.close()
|
On 10/01/2023 04:41, Greg Wilkins wrote:
Mark,
Also relevant is the 2019 discussion in
https://github.com/jakartaee/servlet/issues/273
<https://github.com/jakartaee/servlet/issues/273> where I was again
making the case that complete was a write and should wait for an
isReady()==true before being legal to be called.
You can see that until that point, Jetty was implemented to treat a
close or complete with a write pending as an error. After that
discussion and in response to user reported issues, jetty changed
<https://github.com/eclipse/jetty.project/issues/4331> in Dec 2019 to
follow undertow's model of allowing close and complete to be called with
async operations pending. These changes were also closely associated
with a rethink/reimplement of sendError, which equally became a
non-blocking state change method rather than a potentially blocking
invocation of an error page dispatch.
It was a difficult reimplementation.... so perhaps a touch of
I-don't-want-to-change-it-back bias now makes me think that the state
change model is not so bad.
I can see the benefits of the state change model from the user
perspective as well as the problems for users any attempt switch back
would cause.
I've been looking into the history of the Tomcat implementation for
non-blocking IO and, despite the comments in the test code and the
discussion in the EG, Tomcat has always implemented the state change
model for non-blocking IO. For close, Tomcat took a blocking approach.
It looks to be fairly simple to switch Tomcat to the state change
approach for close. I have most of it implemented already.
My primary concern at this point is to make sure that the results of
this discussion are reflected in the Servlet spec document and the
Javadoc. Hopefully this will remove a large chunk of the ambiguity in
the spec around async and non-blocking IO.
I'm still intended to create an issue with accompanying PR in the next
few days (assuming the consensus to switch to the state change approach
holds).
Mark
cheers
On Tue, 10 Jan 2023 at 03:01, Mark Thomas <markt@xxxxxxxxxx
<mailto:markt@xxxxxxxxxx>> wrote:
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 <https://github.com/apache/tomcat/blame/main/test/org/apache/catalina/nonblocking/TestNonBlockingAPI.java#L823>
[2]
https://github.com/apache/tomcat/commit/690eb5c8d25d0fe26835386057bd455257cbdb86 <https://github.com/apache/tomcat/commit/690eb5c8d25d0fe26835386057bd455257cbdb86>
[3]
https://download.oracle.com/javaee-archive/servlet-spec.java.net/jsr340-experts/2011/09/0056.html <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 <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 <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 <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 <https://github.com/jakartaee/platform-tck/blob/master/src/com/sun/ts/tests/servlet/spec/async/TestServlet.java#L45>
_______________________________________________
servlet-dev mailing list
servlet-dev@xxxxxxxxxxx <mailto:servlet-dev@xxxxxxxxxxx>
To unsubscribe from this list, visit
https://www.eclipse.org/mailman/listinfo/servlet-dev
<https://www.eclipse.org/mailman/listinfo/servlet-dev>
--
Greg Wilkins <gregw@xxxxxxxxxxx <mailto:gregw@xxxxxxxxxxx>> CTO
http://webtide.com <http://webtide.com>
_______________________________________________
servlet-dev mailing list
servlet-dev@xxxxxxxxxxx
To unsubscribe from this list, visit https://www.eclipse.org/mailman/listinfo/servlet-dev