[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
Re: [servlet-dev] Async sendError with error pages?
|
- From: Mark Thomas <markt@xxxxxxxxxx>
- Date: Tue, 9 Jul 2019 16:12:32 +0100
- Autocrypt: addr=markt@xxxxxxxxxx; prefer-encrypt=mutual; keydata= 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
- Delivered-to: servlet-dev@xxxxxxxxxxx
- List-archive: <https://www.eclipse.org/mailman/private/servlet-dev>
- List-help: <mailto:servlet-dev-request@eclipse.org?subject=help>
- List-subscribe: <https://www.eclipse.org/mailman/listinfo/servlet-dev>, <mailto:servlet-dev-request@eclipse.org?subject=subscribe>
- List-unsubscribe: <https://www.eclipse.org/mailman/options/servlet-dev>, <mailto:servlet-dev-request@eclipse.org?subject=unsubscribe>
- Openpgp: preference=signencrypt
- User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.7.2
On 09/07/2019 14:15, Greg Wilkins wrote:
> Mark, Stuart, et al,
Greg,
There are enough edge cases and moving parts here that I want to run
some tests to confirm exactly what happens in some cases. I'll update
this thread when I have some concrete information.
Another factor to bring in to this is the unhandled exception.
Mark
>
> I think that jetty will change to follow the implementations of Tomcat
> and Undertow. Which if I understand correctly is as follows for an
> non-async caller:
>
> * Thread A Normal REQUEST dispatch
> * Thread A calls sendError (state changed, output closed, but response
> not committed)
> * Thread A returns from REQUEST dispatch
> * Thread A output reopened, ERROR dispatch.
> * Thread A generates error page (perhaps calling startAsync and an
> extended lifecycle).
>
> But we'd also like to handle async callers of sendError. Do your
> containers handling it like this?:
>
> * Thread A Normal REQUEST dispatch
> * Thread A calls startAsync
> * Thread B calls sendError (state changed, output closed, but
> response not committed)
> * Winner of race between Thread A returning from REQUEST dispatch and
> Thread B calling complete() does noop
> * Loser of race reopens output and does ERROR dispatch
> * Thread A/B generates page (perhaps calling startAsync and an
> extended lifecycle).
> * Thread A/B calls onComplete when ERROR dispatch returns or second
> async lifecycle completes.
>
> I think that works for an async thread calling sendError then complete,
> but there are some edge cases that need to be considered. What if it
> calls sendError and then AsyncContext.dispatch? What if it calls
> sendError and then times out?
>
> I think that sendError followed by AsyncContext.dispatch should be
> handled with an ISE, just like trying to use a normal dispatcher would
> if sendError had been called.
>
> I'm not sure at all what to do on the timeout. If there is no
> onTimeout listener, then we'd do a ERROR dispatch for the timeout, so
> perhaps we do the same:
>
> * we call any onTimeout listeners, if they call dispatch, then it is
> ISE. If they call complete then we have our complete call and
> proceed as above.
> * If there are no onTimeout listeners or if they don't call complete,
> then we just do the ERROR dispatch for the sendError rather than for
> the timeout?
>
>
> Thoughts?
>
>
> On Mon, 8 Jul 2019 at 04:42, Stuart Douglas <sdouglas@xxxxxxxxxx
> <mailto:sdouglas@xxxxxxxxxx>> wrote:
>
>
>
> On Sat, 6 Jul 2019 at 02:33, Mark Thomas <markt@xxxxxxxxxx
> <mailto:markt@xxxxxxxxxx>> wrote:
>
> On 05/07/2019 10:28, Greg Wilkins wrote:
> >
> > All, as much fun as it is talking about name changes, I'd like
> to have a
> > discussion about the actual semantics of the API :)
>
> What? And make some real progress? It will never catch on.
>
> > We (jetty-project) are currently reviewing how we handle
> sendError when
> > invoked asynchronously with an error page mapping. I'm not
> sure we
> > really have the right semantic in all situations for the
> combinations of
> > async caller and async error page.
>
> Are there use cases for async error pages? My expectation is
> that error
> pages would either be static or would maybe dynamically add some
> error
> information from the request.
>
> I'm not saying we shouldn't support async error pages but it
> does seem
> ... odd.
>
> Generally, Tomcat differs in that when sendError() is called it
> sets an
> error flag but waits until control has returned to the container to
> dispatch to the appropriate error page. The expectation is that
> the app
> returns control immediately after calling sendError() but if it
> doesn't
> Tomcat just ignores anything the app tries to write after
> sendError()
>
> More specific commentary in-line for each case.
>
> > *Non async caller with non async error page. *
> > This is the normal case and the error page is invoked with and
> ERROR
> > dispatch from within the scope of the sendError call. After
> returning,
> > the response is committed and we close the output, so no more
> can be
> > written. The javadoc on says this should be considered:
> >
> > * After using this method, the response should be considered
> > * to be committed and should not be written to.
> >
> > But jetty does enforce it (and I think the TCK tests for this).
>
> Tomcat enforces this and silently swallows any further attempts
> to write
> to the response. This restriction is lifted once the error handling
> takes over so the error page can be written to the response.
>
>
> Undertow is the same.
>
>
> > *Non async caller with async error page.*
> > Here sendError does and ERROR dispatch to the error page,
> which then
> > calls startAsync and returns. Now sendError can't commit nor
> close the
> > response, because it is in a race with async threads that may
> be writing
> > the response. So we use an isAsyncStarted check to avoid
> > committing/closing... so I guess that explains why the javadoc
> only says
> > "considered to be ..."?
>
> Tomcat avoids this race because of when it performs the dispatch.
>
>
> Undertow also does the same, when sendError is called the currently
> running request return to the container before actually doing the
> error dispatch.
>
>
>
> > *Async caller with non-async error page.*
> > A normally dispatched request has called startAsync and then
> an async
> > thread calls sendError. Current releases of jetty do an ERROR
> dispatch
> > to the error page from within the scope of sendError, but we
> now realise
> > that is not correct because the original dispatched thread may
> not yet
> > have exited and we will end up with 1 threads inside the servlet
> > container (and filters etc.) for the same request at the same
> time.
> >
> > So we are considering making the error page dispatch an
> > AsyncContext.dispatch. This solves the concurrency problem,
> but gives
> > us other problems. Should the dispatch type now be ASYNC or
> ERROR?
> > There is no ASYNC_ERROR! Should the calling thread call
> > AsyncContext.complete()? Typically it will because that is
> the contract
> > of async and the caller has no idea if an async dispatch is
> done or not
> > inside the sendError call? So assuming they do call
> complete(), should
> > we just treat it like a noop rather than ISE ?
>
> I'd lean towards using ERROR.
>
>
> +1
>
>
> I think the calling thread should call complete().
>
> What is the dispatch target's justification for calling
> complete()? That
> seems wrong to me so an ISE looks reasonable.
>
>
> I don't know if it is really in line with the spec but we just
> implicitly call complete() here when the error dispatch is done.
>
>
>
> > *Async caller with Async error page.
> > *
> > A normally dispatched request has called startAsync and then
> an async
> > thread calls sendError, which does an async (or error?)
> dispatch to the
> > error page that then calls startAsync again.
>
> That isn't legal is it? Tomcat would throw an ISE in that situation.
>
>
> We would also throw an ISE.
>
>
>
> > We now how two threads
> > that are acting on the same async request. Do we wait for
> both to call
> > complete() before being complete? Surely we have to prevent a
> complete
> > call from the sendError thread from completing the async cycle
> of the
> > error page startAsync? What if one of them calls
> > AsyncContext.dispatch? At this point we are thinking that once a
> > request goes async, then perhaps we should never dispatch to
> an error
> > page from sendError and instead just generate our own simple
> error page?
> >
> > I'd love to know what the other containers do in these situations?
> >
> > I think we obviously need to at least be more specific in our
> javadoc,
> > but I'm thinking that perhaps we might need to change
> behaviour as well
> > to avoid async on async error pages?
>
> I think being more specific would be a good thing.
>
> Would stating that targets of ERROR dispatches must be synchronous a
> possible way forward?
>
>
> I don't really like this. My gut feeling is that that sendError
> should work like javax.servlet.AsyncContext#dispatch, and basically
> finish the current async cycle. If the error page wants to do its
> own async processing then it can just call startAsync again.
>
> Stuart
>
>
>
> Mark
> _______________________________________________
> servlet-dev mailing list
> servlet-dev@xxxxxxxxxxx <mailto:servlet-dev@xxxxxxxxxxx>
> To change your delivery options, retrieve your password, or
> unsubscribe from this list, visit
> https://www.eclipse.org/mailman/listinfo/servlet-dev
>
> _______________________________________________
> servlet-dev mailing list
> servlet-dev@xxxxxxxxxxx <mailto:servlet-dev@xxxxxxxxxxx>
> To change your delivery options, retrieve your password, or
> unsubscribe from this list, visit
> https://www.eclipse.org/mailman/listinfo/servlet-dev
>
>
>
> --
> Greg Wilkins <gregw@xxxxxxxxxxx <mailto:gregw@xxxxxxxxxxx>> CTO
> http://webtide.com
>
> _______________________________________________
> servlet-dev mailing list
> servlet-dev@xxxxxxxxxxx
> To change your delivery options, retrieve your password, or unsubscribe from this list, visit
> https://www.eclipse.org/mailman/listinfo/servlet-dev
>