> Our undersatanding has been that a given request is still thread-locked
from start to finish even though there are changes to the model in how
requests are dispatched, as long as one didn't call out to some kind of
asynchronous API or something that could suspend the processing of the
request.

Incorrect assumption.  Well ... it is an incomplete or partial assumption
really, as it is not limited to only async processing.

Example, All the way back to Servlet 3, if any servlet component declares
async-supported=true (even if they didn't use async) then your thread-local
won't work reliably either across vendors as that was was vaguely defined
in the spec, heck the meaning of *not* declaring async-supported, (what is
the default?) wasn't even defined.  Some vendors took it to mean
async-supported=true was default (Jetty took this approach), others took it
to mean async-supported=false was default (Tomcat took this approach).  It
wasn't until Servlet 4 where the default was defined, let alone all of the
other near constant corner cases in the async processing layer that crops
up with regularity in the servlet spec (re-dispatch, error handling,
wrappers, etc).

Now with the changes in Servlet 5, a container (like Jetty) is free to use
as many threads to service the exchange as it deems appropriate based on
the technology you use, there's no longer an expectation of 1 thread per
exchange (even your 3rd party libraries and web-fragments can change the
behavior without your application being aware of it).  This means
technology choices (not configuration) within the Servlet spec will have a
greater impact on how the threads are being used to service your request.
(choices you won't know at initialization until an application starts to
use those technologies to handle a request).

Example:
If a component uses AsyncContext you have multiple threads. (best choice
here is to use the AsyncContext to reference the request/response)
If a component decides to use Async I/O you have multiple threads as well.
(don't hold onto the request/response here, the container will call into
your application from different threads to satisfy the async I/O behavior)
If a component uses Jakarta WebSockets you have multiple threads (depending
on how you send/receive messages the thread count can be extreme and can
come fast and furious.  And there is an extra requirement to never hold
onto the request/response objects in websocket due to http lifecycle
reasons).

It's a general anti-pattern to hold onto, use, reference a
HttpServletRequest or HttpServletResponse object outside of the dispatch
from the container.
As you can easily create situations of use-after-recycle and super odd
behavior (the spring folks hit this with regularity, and have taken steps
to revert code that holds onto requests/responses outside of the
dispatches, but haven't completed this effort).
Example of the most recent issue they are working:
https://github.com/spring-projects/spring-security/issues/9175

Joakim Erdfelt / joa...@webtide.com

On Wed, Nov 9, 2022 at 3:29 PM Cantor, Scott <canto...@osu.edu> wrote:

> Note that our understanding of the SingleThreadedModel is NOT that it
> changes how a given request is handled, just that it means a servlet is
> forced to allow for multiple requests at once.
>
> That is not an issue for our code, we're fully thread-safe/aware and that
> doesn't break thread-local storage. That's literally how you often make
> things thread-safe in fact.
>
> -- Scott
>
>
> _______________________________________________
> jetty-users mailing list
> jetty-users@eclipse.org
> To unsubscribe from this list, visit
> https://www.eclipse.org/mailman/listinfo/jetty-users
>
_______________________________________________
jetty-users mailing list
jetty-users@eclipse.org
To unsubscribe from this list, visit 
https://www.eclipse.org/mailman/listinfo/jetty-users

Reply via email to