[undertow-dev] Sending response asynchronously to IO or worker thread
Vladimir Tsukur
flushdia at gmail.com
Mon Aug 18 04:19:32 EDT 2014
>
> You don't need the isInIoThread() check, otherwise this handler will do
> nothing if an earlier handler dispatched (e.g. a security handler that
> needed to do a blocking LDAP lookup).
That is true, thanks for pointing it out.
I assume you are not actually dealing with timers and this was just an
> example
Yes, timer was just an example. I am dealing with asynchronous client API
that is used from the handler.
Thanks a lot for the answer!
On Mon, Aug 18, 2014 at 2:42 AM, Stuart Douglas <sdouglas at redhat.com> wrote:
>
>
>> This handler is implemented incorrectly because exchange will end right
>> after handleRequest method is called.
>>
>> In order to fix this we can use dispatching (only implementation of
>> handleRequest method is shown):
>>
>> public void handleRequest(final HttpServerExchange exchange) throws
>> Exception {
>> if (exchange.isInIoThread()) {
>> exchange.dispatch(new Runnable() {
>> public void run() {
>> new Timer().schedule(new TimerTask() {
>> public void run() {
>> Connectors.executeRootHandler(new
>> HttpHandler() {
>> public void
>> handleRequest(HttpServerExchange exchange) throws Exception {
>>
>> exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "text/plain");
>>
>> exchange.getResponseSender().send("Returned in 5 seconds");
>> }
>> }, exchange);
>> }
>> }, 5000);
>> }
>> });
>> }
>> }
>>
>> Please pay attention that the requirement here is not to use dumb
>> blocking in the work thread (like Thread.sleep(5000)) but rely on
>> asynchronous event handling instead.
>>
>> I would appreciate if someone can answer the following questions:
>>
>>
> You don't need the isInIoThread() check, otherwise this handler will do
> nothing if an earlier handler dispatched (e.g. a security handler that
> needed to do a blocking LDAP lookup).
>
> * Are there any pitfalls with the working dispatch/executeRootHandler
>> solution mentioned above?
>>
>
> No, this is the correct way to do it. Undertow's exchange is not thread
> safe (as making it thread safe seriously degrades performance by an order
> of magnitude). Instead multi-threading is implemented by having a safe hand
> off point (the dispatch() method), which basically allows a thread to hand
> off to another thread when it is done, so only one thread 'owns' the
> exchange at a time.
>
> You can just call the dispatch() method with no arguments to stop the
> exchange ending, but if your async task finished before the call stack
> returns then you will have two threads active in the exchange, which will
> cause all kinds of potential problems (this is not going to happen with a
> 5000ms delay, but with a 1ms delay it will).
>
> * Is there a simpler and more elegant way to achieve the same?
>>
>
> I assume you are not actually dealing with timers and this was just an
> example, but if you do want to schedule a task (like a timeout for
> instance) you can schedule it using
>
> exchange.getIoThread().executeAfter(), which will run the timed task in
> the IO thread.
>
> Stuart
>
>
>> --
>> Vladimir Tsukur
>> Software Architect, Design Engineer and Scrum Master
>>
>> _______________________________________________
>> undertow-dev mailing list
>> undertow-dev at lists.jboss.org
>> https://lists.jboss.org/mailman/listinfo/undertow-dev
>>
>
--
Vladimir Tsukur
Software Architect, Design Engineer and Scrum Master
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/undertow-dev/attachments/20140818/7942e679/attachment.html
More information about the undertow-dev
mailing list