On 01/01/2015 11:07, Greg Wilkins wrote:
> 
> On 31 December 2014 at 20:03, Mark Thomas <markt_at_apache.org
> <mailto:markt_at_apache.org>> wrote:
> 
>     > - I don't think any of the possible contexts (original / async started / dispatch
>     > destination ) are correct, so I would prefer to say that no context is
>     > associated with a request that is not synchronously dispatched.
> 
>     I'm yet to be convinced that calling startAsync should remove a
>     request/response pair from a context. I'm open to being convinced but at
>     the moment I'm still of the view:
> 
> 
> 
> I'm not saying that startAsync should remove a request/response pair
> from a context.
> I'm saying that returning from a dispatch to a context should remove
> that request/response pair from the context - regardless of if
> startAsync has been called or not.
Ah. Light dawns (finally).
> The only real issue I see is what is the associated context when the
> dispatched thread has returned from the initial dispatched context and
> startAsync has been called. So for example:
> 
>   * dispatch to context A (enter A listener called & associated context
>     is A)
>   * dispatch to context B (enter B listener called & associated context
>     is B)
>   * startAsync called (associated context is still B)
>   * return from context B (leave B listener called & associated context
>     is A)
>   * return from context A (leave A listeners called? & associated
>     context is ? )
> 
>  I see three options:
> 
>  1. B the context that called startAsync - yuck!  It's like going to the
>     bathroom at a party and coming out in a different party.  There is
>     also the confusion of when the enter/exit listeners should be called
>     - does the request leave B then reenter?
> 
>  2. A the original context that was dispatched to.   This effectively
>     means that if the request is async, the context is never null but is
>     left as the last context the request was in.    I'm kind of OK with
>     this, except that it makes the enter/exit listeners complex to
>     implement/describe.   Any resources allocated by enter/exit
>     resources will be held during the async period - so we will need
>     another set of listeners to represent the async events.
> 
>  3. no context.  This is the clearest and simplest.  It allows us to say
>     that when a dispatched thread leaves a context, the association ends
>     and the listeners are called and this is not dependent on any
>     asynchronous state.
> 
> I think currently jetty implements 3) for the listeners and 2) for the
> getContextPath methods.   I think my preference is for 3) which in full is:
> 
>   * dispatch to context A (enter A listener called & associated context
>     is A)
>   * dispatch to context B (enter B listener called & associated context
>     is B)
>   * startAsync called (associated context is still B)
>   * return from context B (leave B listener called & associated context
>     is A)
>   * return from context A (leave A listener called & associated context
>     is null )
> 
> Simplest and forces async threads to not rely on associated contexts at all.
Of the options you present, I also prefer 3.
However, the part I dislike about this is that a call to
getServletContext() from an async started thread is going to return
different values depending on timing. That strikes me as a recipe for
application bugs. This brings us back to which methods are valid
when/where for async. I think I am saying anything context related is
invalid for anything other than a container thread.
> cheers
> 
> PS. We still have the issue of poorly named enter/exit listeners. 
> Perhaps we need new ones with better names and deprecate the
> create/destroy ones?
I think that is the best option. Something like:
public interface ServletDispatchListener extends EventListener {
  void requestStart (ServletDispatchEvent sre);
  void contextEntry (ServletDispatchEvent sre);
  void contextExit (ServletDispatchEvent sre);
  void requestEnd (ServletDispatchEvent sre);
}
Mark