I hate asking generic questions, but I'm looking for a little understanding
or clarification on request lifecycles. If you haven't noticed, I've had
several recent threads that touch on this. Before anyone asks,
- Yes, I have read all the docs I can find on this Ex
http://undertow.io/undertow-docs/undertow-docs-2.0.0/undertow-request-lif...
http://undertow.io/undertow-docs/undertow-docs-2.0.0/#listeners-2
http://undertow.io/undertow-docs/undertow-docs-2.0.0/servlet-using-non-bl...
- Yes, I have Google and read 3rd party docs and guides on Undertow. Ex:
https://www.oreilly.com/library/view/jboss-developers-guide/9781788296199...
- Yes, I have spent hours reviewing the code and experimenting
I've learned a lot, but there's a couple elusive things that all the docs
and guides I see don't quite seem to satisfactorily explain for me.
I'm trying to get some clarification on exactly what part of the request
happens inside the xnio worker thread and which part runs inside the
ThreadPoolExecutor. My server bootstrap wraps a number of various
HttpHandlers around the handler that I set into the server builder and I
had originally assumed that those handlers were part of the same handler
chain that invoked the servlet. This appears to not be the case. The
handler chain I pass to the server builder appears to execute as part of
the org.xnio.nio.WorkerThread.run() thread, while my servlet code executes
inside a thread pool executor.
Both stack traces show that there is a chain of handler.handleRequest()
calls, but this duality causes some confusion and troubles for me. It also
seems to explain to an extent why Stuart's previous messages treated the
"servlet" as a concept so far removed from the initial handler chain.
Even docs like the last link I provided above that contain this image...
[image: image.png]
make it sound like there is a single "root handler". However,
*executeRootHandler* appears in the stack traces of both the XNIO worker as
well as during the servlet chain in the thread pool executor.
at
io.undertow.server.handlers.SSLHeaderHandler.handleRequest(SSLHeaderHandler.java:105)
*at io.undertow.server.Connectors.executeRootHandler(Connectors.java:376)*
at
io.undertow.server.protocol.http.HttpReadListener.handleEventWithNoRunningRequest(HttpReadListener.java:255)
at
io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:99)
*at io.undertow.server.Connectors.executeRootHandler(Connectors.java:376)*
at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:830)
This has proved to create difficulty in trying to accomplish seemingly very
simple tasks with Undertow. For example, an example I gave in a previous
thread was a simple task of logging every HTTP request that returned a
non-successful status code. Seems easy enough, right? However...
- I can't use an exchange complete listener because it doesn't fire with
handlers like *response-code* that end the exchange
- I can't wrap the servlet handler chain because that chain is never
invoked if the exchange is ended first by my predicates
- I can't wrap the handler chain being run in the XNIO listener because
it doesn't wrap the servlet chain so my "before" and "after"
code all runs
before the servlet chain starts.
I would love any help and insight both on my general question for
documentation regarding the two separate handler chains as well as my more
specific question above about implementing something as simple as a
handler/listener that always runs at the end of an exchange.
Thanks!
~Brad
*Developer Advocate*
*Ortus Solutions, Corp *
E-mail: brad(a)coldbox.org
ColdBox Platform:
http://www.coldbox.org
Blog:
http://www.codersrevolution.com