From mario.e.carbajal at gmail.com Mon Mar 19 09:23:31 2018 From: mario.e.carbajal at gmail.com (Mario Carbajal) Date: Mon, 19 Mar 2018 10:23:31 -0300 Subject: [undertow-dev] Question about endExchange() and response Sender Message-ID: In a dispatched non-blocking HttpRequest handler I'm calling endExchange immediately after calling send on the response Sender. I am unsure if this will cause the sender to be interrupted or if the exchange will end only after the sender is done writing the data. The code looks like this: @Override public void handleRequest(HttpServerExchange exchange) throws Exception { if (exchange.isInIoThread()) { exchange.dispatch(this); return; } try { ... do things ... exchange.getResponseSender().send(data); }finally { exchange.endExchange(); } } -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.jboss.org/pipermail/undertow-dev/attachments/20180319/fa05da27/attachment.html From sdouglas at redhat.com Mon Mar 19 19:42:36 2018 From: sdouglas at redhat.com (Stuart Douglas) Date: Tue, 20 Mar 2018 10:42:36 +1100 Subject: [undertow-dev] Question about endExchange() and response Sender In-Reply-To: References: Message-ID: On Tue, Mar 20, 2018 at 12:23 AM, Mario Carbajal wrote: > In a dispatched non-blocking HttpRequest handler I'm calling endExchange > immediately after calling send on the response Sender. I am unsure if this > will cause the sender to be interrupted or if the exchange will end only > after the sender is done writing the data. > Don't do that. It will appear to work for short responses where the data can be written out in a single write() call, but if it needs to be written out by the IO thread the data will be truncated. Once the send is completed the sender will call endExchange for you, there is no need to do it yourself (assuming you are using the version that does not take a completion callback, the default callback just calls endExchange. If you are using a callback you will need to end it yourself). Stuart > The code looks like this: > > @Override > public void handleRequest(HttpServerExchange exchange) throws Exception > { > if (exchange.isInIoThread()) { > exchange.dispatch(this); > return; > } > > try { > ... do things ... > exchange.getResponseSender().send(data); > }finally { > exchange.endExchange(); > } > } > > > > _______________________________________________ > undertow-dev mailing list > undertow-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/undertow-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.jboss.org/pipermail/undertow-dev/attachments/20180320/11bb22e4/attachment-0001.html From nimtiazm at gmail.com Sun Mar 25 12:31:40 2018 From: nimtiazm at gmail.com (Nabeel Imtiaz) Date: Sun, 25 Mar 2018 20:31:40 +0400 Subject: [undertow-dev] Inconsistency in performing async task Message-ID: Hi, I'm trying to perform expensive tasks (like sending email/sms etc) as an async task (using CompletableFuture API) after my undertow worker completes and i'm about to respond to the client. These tasks are supposed to work like fire and forget and I don't want to wait until the task completes and then respond to the client. I've noticed that sometimes the task doesn't execute and sometimes it does. It's inconsistent and hard to reproduce. Is there a way to be able to perform these async tasks consistently? May be i'm using wrong thread-pool? Or may be there's already a way in Undertow to do such tasks. Please comment. Thanks. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.jboss.org/pipermail/undertow-dev/attachments/20180325/f12aebaa/attachment.html From sdouglas at redhat.com Sun Mar 25 20:50:55 2018 From: sdouglas at redhat.com (Stuart Douglas) Date: Mon, 26 Mar 2018 11:50:55 +1100 Subject: [undertow-dev] Inconsistency in performing async task In-Reply-To: References: Message-ID: How are you running the task? If you just submit it to the worker it should just run like any normal executor. Stuart On Mon, Mar 26, 2018 at 3:31 AM, Nabeel Imtiaz wrote: > Hi, > > I'm trying to perform expensive tasks (like sending email/sms etc) as an > async task (using CompletableFuture API) after my undertow worker completes > and i'm about to respond to the client. These tasks are supposed to work > like fire and forget and I don't want to wait until the task completes and > then respond to the client. > > I've noticed that sometimes the task doesn't execute and sometimes it > does. It's inconsistent and hard to reproduce. Is there a way to be able to > perform these async tasks consistently? May be i'm using wrong thread-pool? > Or may be there's already a way in Undertow to do such tasks. > > Please comment. > > Thanks. > > _______________________________________________ > undertow-dev mailing list > undertow-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/undertow-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.jboss.org/pipermail/undertow-dev/attachments/20180326/35e28dfe/attachment.html From nimtiazm at gmail.com Mon Mar 26 01:29:33 2018 From: nimtiazm at gmail.com (Nabeel Imtiaz) Date: Mon, 26 Mar 2018 09:29:33 +0400 Subject: [undertow-dev] Inconsistency in performing async task In-Reply-To: References: Message-ID: Hi Stuart, Here's the pattern: ``` public void handleRequest... { if (exchange.isInIoThread()) { exchange.dispatch(this); return; } //do some I/O intensive work //... CompletableFuture.supplyAsync(.../*send email with logged exception handling*/...) //#A exchange.getResponseSender().send(responseJson); } ``` The line #A is inconsistent. The task in #A is executed by a thread in common forkjoin pool and may be that could be the reason? I'm not sure. Maybe using one of undertow's worker threads might solve it? Is there a way to do so? All I want is to return response to the client immediately and execute delayable work in the background thread. Thanks. On Mon, Mar 26, 2018 at 4:50 AM, Stuart Douglas wrote: > How are you running the task? If you just submit it to the worker it > should just run like any normal executor. > > Stuart > > On Mon, Mar 26, 2018 at 3:31 AM, Nabeel Imtiaz wrote: > >> Hi, >> >> I'm trying to perform expensive tasks (like sending email/sms etc) as an >> async task (using CompletableFuture API) after my undertow worker completes >> and i'm about to respond to the client. These tasks are supposed to work >> like fire and forget and I don't want to wait until the task completes and >> then respond to the client. >> >> I've noticed that sometimes the task doesn't execute and sometimes it >> does. It's inconsistent and hard to reproduce. Is there a way to be able to >> perform these async tasks consistently? May be i'm using wrong thread-pool? >> Or may be there's already a way in Undertow to do such tasks. >> >> Please comment. >> >> Thanks. >> >> _______________________________________________ >> undertow-dev mailing list >> undertow-dev at lists.jboss.org >> https://lists.jboss.org/mailman/listinfo/undertow-dev >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.jboss.org/pipermail/undertow-dev/attachments/20180326/1de4fc44/attachment.html From sdouglas at redhat.com Mon Mar 26 02:13:51 2018 From: sdouglas at redhat.com (Stuart Douglas) Date: Mon, 26 Mar 2018 17:13:51 +1100 Subject: [undertow-dev] Inconsistency in performing async task In-Reply-To: References: Message-ID: I don't think that has anything to do with Undertow, when you call that method it is out of Undertow's hands (unless you are trying to do something like reading the request from the exchange in the async task, that would be racey). Assuming you are not doing anything like that then it is likey some kind of unrelated bug in your code. Stuart On Mon, Mar 26, 2018 at 4:29 PM, Nabeel Imtiaz wrote: > Hi Stuart, > > Here's the pattern: > > ``` > > public void handleRequest... > > { > > if (exchange.isInIoThread()) > { > exchange.dispatch(this); > return; > } > > //do some I/O intensive work > //... > > CompletableFuture.supplyAsync(.../*send email with logged exception handling*/...) //#A > > exchange.getResponseSender().send(responseJson); > > } > > ``` > > The line #A is inconsistent. The task in #A is executed by a thread in > common forkjoin pool and may be that could be the reason? I'm not sure. > > Maybe using one of undertow's worker threads might solve it? Is there a > way to do so? All I want is to return response to the client immediately > and execute delayable work in the background thread. > > Thanks. > > > On Mon, Mar 26, 2018 at 4:50 AM, Stuart Douglas > wrote: > >> How are you running the task? If you just submit it to the worker it >> should just run like any normal executor. >> >> Stuart >> >> On Mon, Mar 26, 2018 at 3:31 AM, Nabeel Imtiaz >> wrote: >> >>> Hi, >>> >>> I'm trying to perform expensive tasks (like sending email/sms etc) as an >>> async task (using CompletableFuture API) after my undertow worker completes >>> and i'm about to respond to the client. These tasks are supposed to work >>> like fire and forget and I don't want to wait until the task completes and >>> then respond to the client. >>> >>> I've noticed that sometimes the task doesn't execute and sometimes it >>> does. It's inconsistent and hard to reproduce. Is there a way to be able to >>> perform these async tasks consistently? May be i'm using wrong thread-pool? >>> Or may be there's already a way in Undertow to do such tasks. >>> >>> Please comment. >>> >>> Thanks. >>> >>> _______________________________________________ >>> undertow-dev mailing list >>> undertow-dev at lists.jboss.org >>> https://lists.jboss.org/mailman/listinfo/undertow-dev >>> >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.jboss.org/pipermail/undertow-dev/attachments/20180326/cb3d7276/attachment.html From eldadru at gmail.com Wed Mar 28 13:17:26 2018 From: eldadru at gmail.com (Eldad Rudich) Date: Wed, 28 Mar 2018 20:17:26 +0300 Subject: [undertow-dev] dispatching from AsyncReceiverImpl.receivePartialBytes callback fails Message-ID: Hi, In order to read the content of the requests my HttpHandler use receivePartialBytes as follows: public class AsyncReaderHttpHandler implements HttpHandler { @Override public void handleRequest(HttpServerExchange exchange) throws Exception { if (exchange.isInIoThread()) { exchange.dispatch(this); return; } readRequest(exchange); } private void readRequest(HttpServerExchange exchange) { exchange.getRequestReceiver().receivePartialBytes(new MyCallback()); } public class MyCallback implements PartialBytesCallback { @Override public void handle(HttpServerExchange exchange, byte[] message, boolean last) { if (exchange.isInIoThread()) { exchange.dispatch(() -> handleData(exchange, message, last)); } else { handleData(exchange, message, last); } } private void handleData(HttpServerExchange exchange, byte[] message, boolean last) { // do some blocking operation with the data } } } My handler dispatching to worker thread and than calls receivePartialBytes() with a callback. At first, I thought that the handle() method of the callback will always be called from a worker thread context. I was surprised to discover that in some cases the callback will be called from I/O thread (why?), so I had to add the second call to dispatch() inside the callback. After adding the second call to dispatch() my code started to fail with: java.lang.IllegalStateException: UT000146: HttpServerExchange cannot have both async IO resumed and dispatch() called in the same cycle at io.undertow.server.HttpServerExchange$ReadDispatchChannel.resumeReads(HttpServerExchange.java:2100) at io.undertow.io.AsyncReceiverImpl$5$2.handleRequest(AsyncReceiverImpl.java:554) at io.undertow.server.Connectors.executeRootHandler(Connectors.java:332) at io.undertow.io.AsyncReceiverImpl$5.handleEvent(AsyncReceiverImpl.java:549) at io.undertow.io.AsyncReceiverImpl$5.handleEvent(AsyncReceiverImpl.java:516) at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92) at io.undertow.channels.DetachableStreamSourceChannel$SetterDelegatingListener.handleEvent(DetachableStreamSourceChannel.java:231) at io.undertow.channels.DetachableStreamSourceChannel$SetterDelegatingListener.handleEvent(DetachableStreamSourceChannel.java:218) at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92) at org.xnio.conduits.ReadReadyHandler$ChannelListenerHandler.readReady(ReadReadyHandler.java:66) at org.xnio.nio.NioSocketConduit.handleReady(NioSocketConduit.java:88) at org.xnio.nio.WorkerThread.run(WorkerThread.java:561) What am I missing here? how can I use the asynchronous receiver and not risking in blocking I/O thread? I'm using Undertow 1.4.19.Final. Thanks! -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.jboss.org/pipermail/undertow-dev/attachments/20180328/ba4547e4/attachment-0001.html From sdouglas at redhat.com Wed Mar 28 18:25:07 2018 From: sdouglas at redhat.com (Stuart Douglas) Date: Thu, 29 Mar 2018 09:25:07 +1100 Subject: [undertow-dev] dispatching from AsyncReceiverImpl.receivePartialBytes callback fails In-Reply-To: References: Message-ID: You need to call io.undertow.io.Receiver#pause() to pause the IO. This is so that you don't end up with multiple threads working on the exchange. If you don't want to pause (i.e. you hare happy to have more data keep coming and being processed while your blocking task is running) then you do this by just directly submitting the task to the worker, and not calling dispatch. This exists to keep Undertow's operation effectively single threaded, even though the exchange moves between threads one thread is always complete before the next one starts. If you do go with the second option of submitting to the worker you will need to come up with your own way of enforcing 'only one thread using the exchange'. Stuart On Thu, Mar 29, 2018 at 4:17 AM, Eldad Rudich wrote: > Hi, > > In order to read the content of the requests my HttpHandler > use receivePartialBytes as follows: > > public class AsyncReaderHttpHandler implements HttpHandler { > > @Override > public void handleRequest(HttpServerExchange exchange) throws Exception { > > if (exchange.isInIoThread()) { > exchange.dispatch(this); > return; > } > > readRequest(exchange); > } > > private void readRequest(HttpServerExchange exchange) { > exchange.getRequestReceiver().receivePartialBytes(new MyCallback()); > } > > public class MyCallback implements PartialBytesCallback { > > @Override > public void handle(HttpServerExchange exchange, byte[] message, boolean last) { > if (exchange.isInIoThread()) { > exchange.dispatch(() -> handleData(exchange, message, last)); > } else { > handleData(exchange, message, last); > } > } > > private void handleData(HttpServerExchange exchange, byte[] message, boolean last) { > // do some blocking operation with the data > } > } > } > > My handler dispatching to worker thread and than calls > receivePartialBytes() with a callback. > > At first, I thought that the handle() method of the callback will always > be called from a worker thread context. > I was surprised to discover that in some cases the callback will be called > from I/O thread (why?), so I had to add the second call to dispatch() > inside the callback. > > After adding the second call to dispatch() my code started to fail with: > > java.lang.IllegalStateException: UT000146: HttpServerExchange cannot have > both async IO resumed and dispatch() called in the same cycle > at io.undertow.server.HttpServerExchange$ReadDispatchChannel.resumeReads( > HttpServerExchange.java:2100) > at io.undertow.io.AsyncReceiverImpl$5$2.handleRequest( > AsyncReceiverImpl.java:554) > at io.undertow.server.Connectors.executeRootHandler(Connectors.java:332) > at io.undertow.io.AsyncReceiverImpl$5.handleEvent(AsyncReceiverImpl. > java:549) > at io.undertow.io.AsyncReceiverImpl$5.handleEvent(AsyncReceiverImpl. > java:516) > at org.xnio.ChannelListeners.invokeChannelListener( > ChannelListeners.java:92) > at io.undertow.channels.DetachableStreamSourceChannel$ > SetterDelegatingListener.handleEvent(DetachableStreamSourceChannel. > java:231) > at io.undertow.channels.DetachableStreamSourceChannel$ > SetterDelegatingListener.handleEvent(DetachableStreamSourceChannel. > java:218) > at org.xnio.ChannelListeners.invokeChannelListener( > ChannelListeners.java:92) > at org.xnio.conduits.ReadReadyHandler$ChannelListenerHandler. > readReady(ReadReadyHandler.java:66) > at org.xnio.nio.NioSocketConduit.handleReady(NioSocketConduit.java:88) > at org.xnio.nio.WorkerThread.run(WorkerThread.java:561) > > > What am I missing here? how can I use the asynchronous receiver and not > risking in blocking I/O thread? > > I'm using Undertow 1.4.19.Final. > > Thanks! > > _______________________________________________ > undertow-dev mailing list > undertow-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/undertow-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.jboss.org/pipermail/undertow-dev/attachments/20180329/2a0b0932/attachment.html From eldadru at gmail.com Wed Mar 28 18:45:33 2018 From: eldadru at gmail.com (Eldad Rudich) Date: Thu, 29 Mar 2018 01:45:33 +0300 Subject: [undertow-dev] dispatching from AsyncReceiverImpl.receivePartialBytes callback fails In-Reply-To: References: Message-ID: Thanks, Pausing IO is perfect for my use-case, from which context should I call the Receiver#pause() method? within the PartialBytesCallback#handle() method? should I always call pause() or just when handle() called from I/O thread? Should I also call Receiver#resume() or it's automatically done by Undertow? Eldad On Thu, Mar 29, 2018 at 1:25 AM, Stuart Douglas wrote: > You need to call io.undertow.io.Receiver#pause() to pause the IO. This is > so that you don't end up with multiple threads working on the exchange. If > you don't want to pause (i.e. you hare happy to have more data keep coming > and being processed while your blocking task is running) then you do this > by just directly submitting the task to the worker, and not calling > dispatch. > > This exists to keep Undertow's operation effectively single threaded, even > though the exchange moves between threads one thread is always complete > before the next one starts. If you do go with the second option of > submitting to the worker you will need to come up with your own way of > enforcing 'only one thread using the exchange'. > > Stuart > > > > On Thu, Mar 29, 2018 at 4:17 AM, Eldad Rudich wrote: > >> Hi, >> >> In order to read the content of the requests my HttpHandler >> use receivePartialBytes as follows: >> >> public class AsyncReaderHttpHandler implements HttpHandler { >> >> @Override >> public void handleRequest(HttpServerExchange exchange) throws Exception { >> >> if (exchange.isInIoThread()) { >> exchange.dispatch(this); >> return; >> } >> >> readRequest(exchange); >> } >> >> private void readRequest(HttpServerExchange exchange) { >> exchange.getRequestReceiver().receivePartialBytes(new MyCallback()); >> } >> >> public class MyCallback implements PartialBytesCallback { >> >> @Override >> public void handle(HttpServerExchange exchange, byte[] message, boolean last) { >> if (exchange.isInIoThread()) { >> exchange.dispatch(() -> handleData(exchange, message, last)); >> } else { >> handleData(exchange, message, last); >> } >> } >> >> private void handleData(HttpServerExchange exchange, byte[] message, boolean last) { >> // do some blocking operation with the data >> } >> } >> } >> >> My handler dispatching to worker thread and than calls >> receivePartialBytes() with a callback. >> >> At first, I thought that the handle() method of the callback will always >> be called from a worker thread context. >> I was surprised to discover that in some cases the callback will be >> called from I/O thread (why?), so I had to add the second call to >> dispatch() inside the callback. >> >> After adding the second call to dispatch() my code started to fail with: >> >> java.lang.IllegalStateException: UT000146: HttpServerExchange cannot >> have both async IO resumed and dispatch() called in the same cycle >> at io.undertow.server.HttpServerExchange$ReadDispatchChannel.re >> sumeReads(HttpServerExchange.java:2100) >> at io.undertow.io.AsyncReceiverImpl$5$2.handleRequest(AsyncRece >> iverImpl.java:554) >> at io.undertow.server.Connectors.executeRootHandler(Connectors.java:332) >> at io.undertow.io.AsyncReceiverImpl$5.handleEvent( >> AsyncReceiverImpl.java:549) >> at io.undertow.io.AsyncReceiverImpl$5.handleEvent( >> AsyncReceiverImpl.java:516) >> at org.xnio.ChannelListeners.invokeChannelListener(ChannelListe >> ners.java:92) >> at io.undertow.channels.DetachableStreamSourceChannel$SetterDel >> egatingListener.handleEvent(DetachableStreamSourceChannel.java:231) >> at io.undertow.channels.DetachableStreamSourceChannel$SetterDel >> egatingListener.handleEvent(DetachableStreamSourceChannel.java:218) >> at org.xnio.ChannelListeners.invokeChannelListener(ChannelListe >> ners.java:92) >> at org.xnio.conduits.ReadReadyHandler$ChannelListenerHandler.re >> adReady(ReadReadyHandler.java:66) >> at org.xnio.nio.NioSocketConduit.handleReady(NioSocketConduit.java:88) >> at org.xnio.nio.WorkerThread.run(WorkerThread.java:561) >> >> >> What am I missing here? how can I use the asynchronous receiver and not >> risking in blocking I/O thread? >> >> I'm using Undertow 1.4.19.Final. >> >> Thanks! >> >> _______________________________________________ >> undertow-dev mailing list >> undertow-dev at lists.jboss.org >> https://lists.jboss.org/mailman/listinfo/undertow-dev >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.jboss.org/pipermail/undertow-dev/attachments/20180329/da074642/attachment-0001.html