From sdouglas at redhat.com Mon Jan 2 17:46:38 2017 From: sdouglas at redhat.com (Stuart Douglas) Date: Tue, 3 Jan 2017 09:46:38 +1100 Subject: [undertow-dev] Resource Handling Revisited In-Reply-To: References: Message-ID: I would be ok with that, however why can't you just use the ResourceHandler? PathResourceManager will use transferFrom if the file is larger than a configured minimum (the transferMinSize parameter in the constructor). Stuart On Wed, Dec 28, 2016 at 1:52 AM, Hicks, Matt wrote: > Previously I've asked about streaming a single file back to the client and > got some good insight as to how to accomplish this with `transferFrom`, but > this misses out on all the extra features like resuming transfers, cached > content, etc. It would be very nice Undertow offered a static utility > method to serve up File, Path, and URL providing all of this functionality > that is currently contained in ResourceHandler > (https://github.com/undertow-io/undertow/blob/master/core/src/main/java/io/undertow/server/handlers/resource/ResourceHandler.java#L155). > > I don't think it would be difficult to extract all of that out of the > private method and simply have ResourceHandler call the static method. > Stuart, what do you think? > > I'd even be willing to do the leg-work if you'd be willing to accept a PR > for it. > > _______________________________________________ > undertow-dev mailing list > undertow-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/undertow-dev From sdouglas at redhat.com Mon Jan 2 17:52:59 2017 From: sdouglas at redhat.com (Stuart Douglas) Date: Tue, 3 Jan 2017 09:52:59 +1100 Subject: [undertow-dev] IO and Worker Thread based on custom preferences In-Reply-To: References: Message-ID: The easiest way to do this is to use a ServletExtension. Create the extension class, add it to your deployment, and then create a META-INF/services/io.undertow.servlet.ServletExtension entry for it. It will be invoked on deployment. Something like the following class should do what you are after: private class MyExtension implements ServletExtension { @Override public void handleDeployment(DeploymentInfo deploymentInfo, ServletContext servletContext) { final ExecutorService executor = Executors.newFixedThreadPool(1); //create the executor deploymentInfo.addInitialHandlerChainWrapper(new HandlerWrapper() { //handlers that will run before any servlet functionality @Override public HttpHandler wrap(final HttpHandler handler) { return new PredicateHandler(Predicates.path("/myurl"), new HttpHandler() { //only run this if the predicate matches (in this case /myurl) @Override public void handleRequest(HttpServerExchange exchange) throws Exception { exchange.setDispatchExecutor(executor); handler.handleRequest(exchange); } }, handler); } }); //add a listener to shut down the pool on undeploy servletContext.addListener(new ServletContextListener() { @Override public void contextInitialized(ServletContextEvent sce) { } @Override public void contextDestroyed(ServletContextEvent sce) { executor.shutdown(); } }); } } On Wed, Dec 28, 2016 at 7:46 PM, tone randomnaja wrote: > Hi Stuart, > > Request limit might be insufficient, could you share how to implement the > custom handler and possibly how to deploy this custom handler to Wildfly ? > > Regards, > > On Dec 23, 2016 04:36, "Stuart Douglas" wrote: >> >> You would need to write a custom handler to set the thread pool if you >> want to do this in Wildfly, however if you just want to limit the number of >> active requests in a given path you may want to just use the request >> limiting handler instead. >> >> In WEB-INF/undertow-handlers.conf try adding something like the following: >> >> path-prefix(/mypath) -> request-limit(10) >> >> This will limit the number of requests that can be active in /mypath/* to >> 10. >> >> If you actually need to use a thread pool and the request limit is not >> sufficient let me know and I can point you in the right direction. >> >> Stuart >> >> >> On Fri, Dec 23, 2016 at 12:07 AM, Bill O'Neil wrote: >>> >>> I only use undertow directly I haven't looked at Wildfly before so I >>> won't be able to answer your question sorry. >>> >>> On Thu, Dec 22, 2016 at 7:55 AM, tone randomnaja >>> wrote: >>>> >>>> Thanks, >>>> >>>> And let's say if I had custom executor, how could I set the >>>> DispatchExecutor ? (from Wildfly point-of-view) >>>> Could it be another module being placed inside system lib of Wildfly ? >>>> >>>> ps. I'm pretty sure, I'd not have done this within Application (EAR/WAR) >>>> itself ? >>>> >>>> On Thu, Dec 22, 2016 at 6:43 PM, Bill O'Neil wrote: >>>>> >>>>> This might be what you are looking for. >>>>> >>>>> >>>>> https://github.com/undertow-io/undertow/blob/master/core/src/main/java/io/undertow/server/HttpServerExchange.java#L821 >>>>> >>>>> You can change the dispatch executor to your own custom executor before >>>>> you call dispatch. This will allow you to have different worker pools and >>>>> configure them per HttpHandler. >>>>> >>>>> On Thu, Dec 22, 2016 at 6:16 AM, tone randomnaja >>>>> wrote: >>>>>> >>>>>> Hi there ! >>>>>> >>>>>> Undertow has `IO Thread` and `Worker Thread` configuration (>>>>> xmlns="urn:jboss:domain:io:1.1">>>>>> bounded per Listener (>>>>> >>>>>> In my case I have 1 Listenner (AJP) and 1 Application (EAR), >>>>>> I'd like to be able to priority and manage Worker Thread base on some >>>>>> preferences, such as URL path. >>>>>> >>>>>> Above for a reason of controlling the load of specific URL (under the >>>>>> same Web Context). >>>>>> >>>>>> Any suggestions or ideas ? >>>>>> >>>>>> _______________________________________________ >>>>>> undertow-dev mailing list >>>>>> undertow-dev at lists.jboss.org >>>>>> https://lists.jboss.org/mailman/listinfo/undertow-dev >>>>> >>>>> >>>> >>> >>> >>> _______________________________________________ >>> undertow-dev mailing list >>> undertow-dev at lists.jboss.org >>> https://lists.jboss.org/mailman/listinfo/undertow-dev >> >> > From matt at matthicks.com Mon Jan 2 21:50:11 2017 From: matt at matthicks.com (Hicks, Matt) Date: Tue, 03 Jan 2017 02:50:11 +0000 Subject: [undertow-dev] Resource Handling Revisited In-Reply-To: References: Message-ID: The problem with ResourceHandler is it doesn't easily support more complex scenarios. A few examples: security on resources, URLs that must find a resource path from the database, conditional resources (deliver resource A if the IP is x.x.x.x and resource B otherwise), etc. Offering a more granular control to allow delivery of individual resources without the need of a ResourceHandler will drastically improve the flexibility of Undertow. On Mon, Jan 2, 2017 at 4:46 PM Stuart Douglas wrote: > I would be ok with that, however why can't you just use the > ResourceHandler? PathResourceManager will use transferFrom if the file > is larger than a configured minimum (the transferMinSize parameter in > the constructor). > > Stuart > > On Wed, Dec 28, 2016 at 1:52 AM, Hicks, Matt wrote: > > Previously I've asked about streaming a single file back to the client > and > > got some good insight as to how to accomplish this with `transferFrom`, > but > > this misses out on all the extra features like resuming transfers, cached > > content, etc. It would be very nice Undertow offered a static utility > > method to serve up File, Path, and URL providing all of this > functionality > > that is currently contained in ResourceHandler > > ( > https://github.com/undertow-io/undertow/blob/master/core/src/main/java/io/undertow/server/handlers/resource/ResourceHandler.java#L155 > ). > > > > I don't think it would be difficult to extract all of that out of the > > private method and simply have ResourceHandler call the static method. > > Stuart, what do you think? > > > > I'd even be willing to do the leg-work if you'd be willing to accept a PR > > for it. > > > > _______________________________________________ > > 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/20170103/4be6edf6/attachment.html From bill at dartalley.com Mon Jan 2 21:59:40 2017 From: bill at dartalley.com (Bill O'Neil) Date: Mon, 2 Jan 2017 21:59:40 -0500 Subject: [undertow-dev] Resource Handling Revisited In-Reply-To: References: Message-ID: You should be able to handle all of your use cases by composing handlers together. Create a new handler that handles security or the database logic then delegates to an internal resource handler with the appropriate path. On Mon, Jan 2, 2017 at 9:50 PM, Hicks, Matt wrote: > The problem with ResourceHandler is it doesn't easily support more complex > scenarios. A few examples: security on resources, URLs that must find a > resource path from the database, conditional resources (deliver resource A > if the IP is x.x.x.x and resource B otherwise), etc. > > Offering a more granular control to allow delivery of individual resources > without the need of a ResourceHandler will drastically improve the > flexibility of Undertow. > > On Mon, Jan 2, 2017 at 4:46 PM Stuart Douglas wrote: > >> I would be ok with that, however why can't you just use the >> ResourceHandler? PathResourceManager will use transferFrom if the file >> is larger than a configured minimum (the transferMinSize parameter in >> the constructor). >> >> Stuart >> >> On Wed, Dec 28, 2016 at 1:52 AM, Hicks, Matt wrote: >> > Previously I've asked about streaming a single file back to the client >> and >> > got some good insight as to how to accomplish this with `transferFrom`, >> but >> > this misses out on all the extra features like resuming transfers, >> cached >> > content, etc. It would be very nice Undertow offered a static utility >> > method to serve up File, Path, and URL providing all of this >> functionality >> > that is currently contained in ResourceHandler >> > (https://github.com/undertow-io/undertow/blob/master/core/ >> src/main/java/io/undertow/server/handlers/resource/ >> ResourceHandler.java#L155). >> > >> > I don't think it would be difficult to extract all of that out of the >> > private method and simply have ResourceHandler call the static method. >> > Stuart, what do you think? >> > >> > I'd even be willing to do the leg-work if you'd be willing to accept a >> PR >> > for it. >> > >> > _______________________________________________ >> > undertow-dev mailing list >> > undertow-dev at lists.jboss.org >> > https://lists.jboss.org/mailman/listinfo/undertow-dev >> > > _______________________________________________ > 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/20170102/42d7892c/attachment.html From matt at matthicks.com Tue Jan 3 10:09:16 2017 From: matt at matthicks.com (Hicks, Matt) Date: Tue, 03 Jan 2017 15:09:16 +0000 Subject: [undertow-dev] Resource Handling Revisited In-Reply-To: References: Message-ID: Bill, though you're probably right, I still believe this would be useful functionality for one-off resource handling without requiring a resource handler. On Mon, Jan 2, 2017 at 8:59 PM Bill O'Neil wrote: > You should be able to handle all of your use cases by composing handlers > together. Create a new handler that handles security or the database logic > then delegates to an internal resource handler with the appropriate path. > > On Mon, Jan 2, 2017 at 9:50 PM, Hicks, Matt wrote: > > The problem with ResourceHandler is it doesn't easily support more complex > scenarios. A few examples: security on resources, URLs that must find a > resource path from the database, conditional resources (deliver resource A > if the IP is x.x.x.x and resource B otherwise), etc. > > Offering a more granular control to allow delivery of individual resources > without the need of a ResourceHandler will drastically improve the > flexibility of Undertow. > > On Mon, Jan 2, 2017 at 4:46 PM Stuart Douglas wrote: > > I would be ok with that, however why can't you just use the > ResourceHandler? PathResourceManager will use transferFrom if the file > is larger than a configured minimum (the transferMinSize parameter in > the constructor). > > Stuart > > On Wed, Dec 28, 2016 at 1:52 AM, Hicks, Matt wrote: > > Previously I've asked about streaming a single file back to the client > and > > got some good insight as to how to accomplish this with `transferFrom`, > but > > this misses out on all the extra features like resuming transfers, cached > > content, etc. It would be very nice Undertow offered a static utility > > method to serve up File, Path, and URL providing all of this > functionality > > that is currently contained in ResourceHandler > > ( > https://github.com/undertow-io/undertow/blob/master/core/src/main/java/io/undertow/server/handlers/resource/ResourceHandler.java#L155 > ). > > > > I don't think it would be difficult to extract all of that out of the > > private method and simply have ResourceHandler call the static method. > > Stuart, what do you think? > > > > I'd even be willing to do the leg-work if you'd be willing to accept a PR > > for it. > > > > _______________________________________________ > > undertow-dev mailing list > > undertow-dev at lists.jboss.org > > https://lists.jboss.org/mailman/listinfo/undertow-dev > > > _______________________________________________ > 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/20170103/f6d6da23/attachment-0001.html From sdouglas at redhat.com Tue Jan 3 15:48:16 2017 From: sdouglas at redhat.com (Stuart Douglas) Date: Wed, 4 Jan 2017 07:48:16 +1100 Subject: [undertow-dev] Resource Handling Revisited In-Reply-To: References: Message-ID: If you submit a PR I would be happy to look at it. Stuart On Wed, Jan 4, 2017 at 2:09 AM, Hicks, Matt wrote: > Bill, though you're probably right, I still believe this would be useful > functionality for one-off resource handling without requiring a resource > handler. > > On Mon, Jan 2, 2017 at 8:59 PM Bill O'Neil wrote: >> >> You should be able to handle all of your use cases by composing handlers >> together. Create a new handler that handles security or the database logic >> then delegates to an internal resource handler with the appropriate path. >> >> On Mon, Jan 2, 2017 at 9:50 PM, Hicks, Matt wrote: >>> >>> The problem with ResourceHandler is it doesn't easily support more >>> complex scenarios. A few examples: security on resources, URLs that must >>> find a resource path from the database, conditional resources (deliver >>> resource A if the IP is x.x.x.x and resource B otherwise), etc. >>> >>> Offering a more granular control to allow delivery of individual >>> resources without the need of a ResourceHandler will drastically improve the >>> flexibility of Undertow. >>> >>> On Mon, Jan 2, 2017 at 4:46 PM Stuart Douglas >>> wrote: >>>> >>>> I would be ok with that, however why can't you just use the >>>> ResourceHandler? PathResourceManager will use transferFrom if the file >>>> is larger than a configured minimum (the transferMinSize parameter in >>>> the constructor). >>>> >>>> Stuart >>>> >>>> On Wed, Dec 28, 2016 at 1:52 AM, Hicks, Matt wrote: >>>> > Previously I've asked about streaming a single file back to the client >>>> > and >>>> > got some good insight as to how to accomplish this with >>>> > `transferFrom`, but >>>> > this misses out on all the extra features like resuming transfers, >>>> > cached >>>> > content, etc. It would be very nice Undertow offered a static utility >>>> > method to serve up File, Path, and URL providing all of this >>>> > functionality >>>> > that is currently contained in ResourceHandler >>>> > >>>> > (https://github.com/undertow-io/undertow/blob/master/core/src/main/java/io/undertow/server/handlers/resource/ResourceHandler.java#L155). >>>> > >>>> > I don't think it would be difficult to extract all of that out of the >>>> > private method and simply have ResourceHandler call the static method. >>>> > Stuart, what do you think? >>>> > >>>> > I'd even be willing to do the leg-work if you'd be willing to accept a >>>> > PR >>>> > for it. >>>> > >>>> > _______________________________________________ >>>> > undertow-dev mailing list >>>> > undertow-dev at lists.jboss.org >>>> > https://lists.jboss.org/mailman/listinfo/undertow-dev >>> >>> >>> _______________________________________________ >>> undertow-dev mailing list >>> undertow-dev at lists.jboss.org >>> https://lists.jboss.org/mailman/listinfo/undertow-dev >> >> > From mike at stardog.com Fri Jan 6 15:19:49 2017 From: mike at stardog.com (Michael Grove) Date: Fri, 6 Jan 2017 15:19:49 -0500 Subject: [undertow-dev] when exactly are the headers and such written to the client? Message-ID: I'm using EncodingHandler for gzip encoding of responses and I'm not seeing the header on the client, but I have a breakpoint in AllowedContentEncodings L95, and it's definitely hit, but I'm wondering if it's hit after the initial part of the response is written so that header isnt ever sent. My handler dispatches to a worker thread if need be, does the biz logic, calls startBlocking on the exchange, sets the status code and other headers like Content-Type, and then writes the results to the stream from HttpServerExchange#getOutputStream before calling endExchange. I can see the Content-Type header correctly set, but not Content-Encoding. The javadocs say they're written when the first write is initiated, but I have't managed to find where that is, specifically in relation to the EncodingHandler. Hoping someone can point me in the right direction or with any luck, have a guess at what I've messed up. Thanks. Mike -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.jboss.org/pipermail/undertow-dev/attachments/20170106/cfd824cf/attachment.html From matt at matthicks.com Fri Jan 6 16:06:38 2017 From: matt at matthicks.com (Hicks, Matt) Date: Fri, 06 Jan 2017 21:06:38 +0000 Subject: [undertow-dev] Resource Handling Revisited In-Reply-To: References: Message-ID: It took me a while to get the time to do this, but I just submitted a PR that extracts the functionality into an AbstractResourceHandler to allow other methodologies without compromising the existing paradigm. https://github.com/undertow-io/undertow/pull/470 I wasn't able to extract it into a static method as there are too many configuration options that it needs access to for it to be practical. On Tue, Jan 3, 2017 at 2:48 PM Stuart Douglas wrote: > If you submit a PR I would be happy to look at it. > > Stuart > > On Wed, Jan 4, 2017 at 2:09 AM, Hicks, Matt wrote: > > Bill, though you're probably right, I still believe this would be useful > > functionality for one-off resource handling without requiring a resource > > handler. > > > > On Mon, Jan 2, 2017 at 8:59 PM Bill O'Neil wrote: > >> > >> You should be able to handle all of your use cases by composing handlers > >> together. Create a new handler that handles security or the database > logic > >> then delegates to an internal resource handler with the appropriate > path. > >> > >> On Mon, Jan 2, 2017 at 9:50 PM, Hicks, Matt wrote: > >>> > >>> The problem with ResourceHandler is it doesn't easily support more > >>> complex scenarios. A few examples: security on resources, URLs that > must > >>> find a resource path from the database, conditional resources (deliver > >>> resource A if the IP is x.x.x.x and resource B otherwise), etc. > >>> > >>> Offering a more granular control to allow delivery of individual > >>> resources without the need of a ResourceHandler will drastically > improve the > >>> flexibility of Undertow. > >>> > >>> On Mon, Jan 2, 2017 at 4:46 PM Stuart Douglas > >>> wrote: > >>>> > >>>> I would be ok with that, however why can't you just use the > >>>> ResourceHandler? PathResourceManager will use transferFrom if the file > >>>> is larger than a configured minimum (the transferMinSize parameter in > >>>> the constructor). > >>>> > >>>> Stuart > >>>> > >>>> On Wed, Dec 28, 2016 at 1:52 AM, Hicks, Matt > wrote: > >>>> > Previously I've asked about streaming a single file back to the > client > >>>> > and > >>>> > got some good insight as to how to accomplish this with > >>>> > `transferFrom`, but > >>>> > this misses out on all the extra features like resuming transfers, > >>>> > cached > >>>> > content, etc. It would be very nice Undertow offered a static > utility > >>>> > method to serve up File, Path, and URL providing all of this > >>>> > functionality > >>>> > that is currently contained in ResourceHandler > >>>> > > >>>> > ( > https://github.com/undertow-io/undertow/blob/master/core/src/main/java/io/undertow/server/handlers/resource/ResourceHandler.java#L155 > ). > >>>> > > >>>> > I don't think it would be difficult to extract all of that out of > the > >>>> > private method and simply have ResourceHandler call the static > method. > >>>> > Stuart, what do you think? > >>>> > > >>>> > I'd even be willing to do the leg-work if you'd be willing to > accept a > >>>> > PR > >>>> > for it. > >>>> > > >>>> > _______________________________________________ > >>>> > undertow-dev mailing list > >>>> > undertow-dev at lists.jboss.org > >>>> > https://lists.jboss.org/mailman/listinfo/undertow-dev > >>> > >>> > >>> _______________________________________________ > >>> 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/20170106/98ab077b/attachment.html From sdouglas at redhat.com Sun Jan 8 15:17:29 2017 From: sdouglas at redhat.com (Stuart Douglas) Date: Mon, 9 Jan 2017 07:17:29 +1100 Subject: [undertow-dev] when exactly are the headers and such written to the client? In-Reply-To: References: Message-ID: They are written on the first write that makes it to the io.undertow.server.protocol.http.HttpResponseConduit. If you are using content encoding this may not actually correspond to the first write your application does, and if you are using output streams writes are also buffered, so you need to either fill the buffer or call flush() to force a write. If you see that line being hit in AllowedContentEncodings then the header should definitely be set, unless something is then clearing it. Stuart On Sat, Jan 7, 2017 at 7:19 AM, Michael Grove wrote: > I'm using EncodingHandler for gzip encoding of responses and I'm not seeing > the header on the client, but I have a breakpoint in AllowedContentEncodings > L95, and it's definitely hit, but I'm wondering if it's hit after the > initial part of the response is written so that header isnt ever sent. > > My handler dispatches to a worker thread if need be, does the biz logic, > calls startBlocking on the exchange, sets the status code and other headers > like Content-Type, and then writes the results to the stream from > HttpServerExchange#getOutputStream before calling endExchange. > > I can see the Content-Type header correctly set, but not Content-Encoding. > The javadocs say they're written when the first write is initiated, but I > have't managed to find where that is, specifically in relation to the > EncodingHandler. Hoping someone can point me in the right direction or with > any luck, have a guess at what I've messed up. > > Thanks. > > Mike > > _______________________________________________ > undertow-dev mailing list > undertow-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/undertow-dev From randomnaja at gmail.com Wed Jan 11 10:12:27 2017 From: randomnaja at gmail.com (tone randomnaja) Date: Wed, 11 Jan 2017 22:12:27 +0700 Subject: [undertow-dev] Another questions based on UNDERTOW-349, what was wrong Message-ID: Hi all, I'd like to have understanding of what was going on with https://issues.jboss.org/browse/UNDERTOW-349, in which under some circumstance the io.undertow.server.handlers.RequestLimit got corrupted and could not process Queue correctly, probably someone could kindly explain me more ? btw. after digest below mailing list, I still could not figure out what was wrong with RequestLimit ( http://lists.jboss.org/pipermail/undertow-dev/2014-December/001049.html ) -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.jboss.org/pipermail/undertow-dev/attachments/20170111/acd3dc4a/attachment-0001.html From sdouglas at redhat.com Wed Jan 11 15:13:39 2017 From: sdouglas at redhat.com (Stuart Douglas) Date: Thu, 12 Jan 2017 07:13:39 +1100 Subject: [undertow-dev] Another questions based on UNDERTOW-349, what was wrong In-Reply-To: References: Message-ID: The exchange completion listener was added two early. If a request was rejected then this would cause the count to go negative (as the count would be decreased without ever having been increased). Stuart On Thu, Jan 12, 2017 at 2:12 AM, tone randomnaja wrote: > Hi all, > > I'd like to have understanding of what was going on with > https://issues.jboss.org/browse/UNDERTOW-349, in which under some > circumstance the io.undertow.server.handlers.RequestLimit got corrupted and > could not process Queue correctly, > > probably someone could kindly explain me more ? > > btw. after digest below mailing list, I still could not figure out what was > wrong with RequestLimit ( > http://lists.jboss.org/pipermail/undertow-dev/2014-December/001049.html ) > > _______________________________________________ > undertow-dev mailing list > undertow-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/undertow-dev From randomnaja at gmail.com Wed Jan 11 23:07:26 2017 From: randomnaja at gmail.com (tone randomnaja) Date: Thu, 12 Jan 2017 11:07:26 +0700 Subject: [undertow-dev] Another questions based on UNDERTOW-349, what was wrong In-Reply-To: References: Message-ID: how the request was rejected ? by which criteria or event ? On Jan 12, 2017 03:13, "Stuart Douglas" wrote: > The exchange completion listener was added two early. If a request was > rejected then this would cause the count to go negative (as the count > would be decreased without ever having been increased). > > Stuart > > On Thu, Jan 12, 2017 at 2:12 AM, tone randomnaja > wrote: > > Hi all, > > > > I'd like to have understanding of what was going on with > > https://issues.jboss.org/browse/UNDERTOW-349, in which under some > > circumstance the io.undertow.server.handlers.RequestLimit got corrupted > and > > could not process Queue correctly, > > > > probably someone could kindly explain me more ? > > > > btw. after digest below mailing list, I still could not figure out what > was > > wrong with RequestLimit ( > > http://lists.jboss.org/pipermail/undertow-dev/2014-December/001049.html > ) > > > > _______________________________________________ > > 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/20170112/0157b260/attachment.html From sdouglas at redhat.com Wed Jan 11 23:23:16 2017 From: sdouglas at redhat.com (Stuart Douglas) Date: Thu, 12 Jan 2017 15:23:16 +1100 Subject: [undertow-dev] Another questions based on UNDERTOW-349, what was wrong In-Reply-To: References: Message-ID: If there was a max queue size and the queue was full the request would be rejected. Stuart On Thu, Jan 12, 2017 at 3:07 PM, tone randomnaja wrote: > how the request was rejected ? by which criteria or event ? > > On Jan 12, 2017 03:13, "Stuart Douglas" wrote: >> >> The exchange completion listener was added two early. If a request was >> rejected then this would cause the count to go negative (as the count >> would be decreased without ever having been increased). >> >> Stuart >> >> On Thu, Jan 12, 2017 at 2:12 AM, tone randomnaja >> wrote: >> > Hi all, >> > >> > I'd like to have understanding of what was going on with >> > https://issues.jboss.org/browse/UNDERTOW-349, in which under some >> > circumstance the io.undertow.server.handlers.RequestLimit got corrupted >> > and >> > could not process Queue correctly, >> > >> > probably someone could kindly explain me more ? >> > >> > btw. after digest below mailing list, I still could not figure out what >> > was >> > wrong with RequestLimit ( >> > http://lists.jboss.org/pipermail/undertow-dev/2014-December/001049.html >> > ) >> > >> > _______________________________________________ >> > undertow-dev mailing list >> > undertow-dev at lists.jboss.org >> > https://lists.jboss.org/mailman/listinfo/undertow-dev From randomnaja at gmail.com Thu Jan 12 00:01:44 2017 From: randomnaja at gmail.com (tone randomnaja) Date: Thu, 12 Jan 2017 12:01:44 +0700 Subject: [undertow-dev] Another questions based on UNDERTOW-349, what was wrong In-Reply-To: References: Message-ID: Oh, I through that failureHandle would also get the Exchange completed, and listenner be called ? On Jan 12, 2017 11:23, "Stuart Douglas" wrote: > If there was a max queue size and the queue was full the request would > be rejected. > > Stuart > > On Thu, Jan 12, 2017 at 3:07 PM, tone randomnaja > wrote: > > how the request was rejected ? by which criteria or event ? > > > > On Jan 12, 2017 03:13, "Stuart Douglas" wrote: > >> > >> The exchange completion listener was added two early. If a request was > >> rejected then this would cause the count to go negative (as the count > >> would be decreased without ever having been increased). > >> > >> Stuart > >> > >> On Thu, Jan 12, 2017 at 2:12 AM, tone randomnaja > >> wrote: > >> > Hi all, > >> > > >> > I'd like to have understanding of what was going on with > >> > https://issues.jboss.org/browse/UNDERTOW-349, in which under some > >> > circumstance the io.undertow.server.handlers.RequestLimit got > corrupted > >> > and > >> > could not process Queue correctly, > >> > > >> > probably someone could kindly explain me more ? > >> > > >> > btw. after digest below mailing list, I still could not figure out > what > >> > was > >> > wrong with RequestLimit ( > >> > http://lists.jboss.org/pipermail/undertow-dev/2014- > December/001049.html > >> > ) > >> > > >> > _______________________________________________ > >> > 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/20170112/ab68fa35/attachment.html From bill at dartalley.com Sat Jan 14 15:22:23 2017 From: bill at dartalley.com (Bill O'Neil) Date: Sat, 14 Jan 2017 15:22:23 -0500 Subject: [undertow-dev] Testing custom HttpHandlers Message-ID: Hello, How would you recommend testing custom HttpHanders? The DefaultServer class in core part of the test code so it is not included in the jar for reuse. Would it be reasonable to pull testing utils into their own project so it can be reused? Or would you recommend just mocking a HttpServerExchange and passing that to the HttpHandler? Thanks, Bill -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.jboss.org/pipermail/undertow-dev/attachments/20170114/9f844819/attachment.html From sdouglas at redhat.com Sun Jan 15 17:32:49 2017 From: sdouglas at redhat.com (Stuart Douglas) Date: Mon, 16 Jan 2017 09:32:49 +1100 Subject: [undertow-dev] Testing custom HttpHandlers In-Reply-To: References: Message-ID: We do publish tests-jars, so you can actually use DefaultServer, however I agree that this is not really ideal. I think the ideal solution would be to take the core functionality from DefaultServer and create a new repo (undertow-test-runner) and create some kind of UndertowRunner class that is based on DefaultServer. Does this sound reasonable? Stuart On Sun, Jan 15, 2017 at 7:22 AM, Bill O'Neil wrote: > Hello, > > How would you recommend testing custom HttpHanders? The DefaultServer class > in core part of the test code so it is not included in the jar for reuse. > Would it be reasonable to pull testing utils into their own project so it > can be reused? Or would you recommend just mocking a HttpServerExchange and > passing that to the HttpHandler? > > Thanks, > Bill > > _______________________________________________ > undertow-dev mailing list > undertow-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/undertow-dev From bill at dartalley.com Mon Jan 16 20:59:14 2017 From: bill at dartalley.com (Bill O'Neil) Date: Mon, 16 Jan 2017 20:59:14 -0500 Subject: [undertow-dev] Testing custom HttpHandlers In-Reply-To: References: Message-ID: Whatever you think is best. I'm fine following Steve's approach. Undertow starts up and shuts down pretty quick. On Sun, Jan 15, 2017 at 5:32 PM, Stuart Douglas wrote: > We do publish tests-jars, so you can actually use DefaultServer, > however I agree that this is not really ideal. > > I think the ideal solution would be to take the core functionality > from DefaultServer and create a new repo (undertow-test-runner) and > create some kind of UndertowRunner class that is based on > DefaultServer. Does this sound reasonable? > > > Stuart > > On Sun, Jan 15, 2017 at 7:22 AM, Bill O'Neil wrote: > > Hello, > > > > How would you recommend testing custom HttpHanders? The DefaultServer > class > > in core part of the test code so it is not included in the jar for reuse. > > Would it be reasonable to pull testing utils into their own project so it > > can be reused? Or would you recommend just mocking a HttpServerExchange > and > > passing that to the HttpHandler? > > > > Thanks, > > Bill > > > > _______________________________________________ > > 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/20170116/c00b704d/attachment-0001.html From miere.teixeira at gmail.com Wed Jan 18 15:53:53 2017 From: miere.teixeira at gmail.com (Miere Teixeira) Date: Wed, 18 Jan 2017 20:53:53 +0000 Subject: [undertow-dev] Is it safe to ignore this DEBUG message? Message-ID: Hi there! I've changed the way my HttpHandlers are reading the body content (JSON) on POST requests, reading them asynchronously as explained here . Since then, my application log started to display messages like the following one: 18:28:20.807 [XNIO-1 I/O-4] DEBUG io.undertow.request - UT005035: Closing channel because of parse timeout for remote address /0:0:0:0:0:0:0:1:51781 Is it safe to ignore it? Is there something I should pay attention to use exchange.getRequestReceiver().receiveFullBytes? Regards! Miere -- Miere Teixeira -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.jboss.org/pipermail/undertow-dev/attachments/20170118/00dc1cc5/attachment.html From sdouglas at redhat.com Wed Jan 18 16:04:52 2017 From: sdouglas at redhat.com (Stuart Douglas) Date: Thu, 19 Jan 2017 08:04:52 +1100 Subject: [undertow-dev] Is it safe to ignore this DEBUG message? In-Reply-To: References: Message-ID: That is nothing to worry about. It is actually a minor bug in the message, it looks like you get the same message for both parse and idle timeout. Either way it means the remote client has not sent any data in a while, and Undertow is closing the connection as a result. Stuart On Thu, Jan 19, 2017 at 7:53 AM, Miere Teixeira wrote: > Hi there! > > I've changed the way my HttpHandlers are reading the body content (JSON) on > POST requests, reading them asynchronously as explained here. > Since then, my application log started to display messages like the > following one: > 18:28:20.807 [XNIO-1 I/O-4] DEBUG io.undertow.request - UT005035: Closing > channel because of parse timeout for remote address /0:0:0:0:0:0:0:1:51781 > > Is it safe to ignore it? Is there something I should pay attention to use > exchange.getRequestReceiver().receiveFullBytes? > > Regards! > Miere > -- > > Miere Teixeira > > > _______________________________________________ > undertow-dev mailing list > undertow-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/undertow-dev From miere.teixeira at gmail.com Wed Jan 18 17:21:05 2017 From: miere.teixeira at gmail.com (Miere Teixeira) Date: Wed, 18 Jan 2017 22:21:05 +0000 Subject: [undertow-dev] Is it safe to ignore this DEBUG message? In-Reply-To: References: Message-ID: Ok, thanks for the fast reply. On Wed, Jan 18, 2017 at 7:04 PM Stuart Douglas wrote: > That is nothing to worry about. It is actually a minor bug in the > message, it looks like you get the same message for both parse and > idle timeout. Either way it means the remote client has not sent any > data in a while, and Undertow is closing the connection as a result. > > Stuart > > On Thu, Jan 19, 2017 at 7:53 AM, Miere Teixeira > wrote: > > Hi there! > > > > I've changed the way my HttpHandlers are reading the body content (JSON) > on > > POST requests, reading them asynchronously as explained here. > > Since then, my application log started to display messages like the > > following one: > > 18:28:20.807 [XNIO-1 I/O-4] DEBUG io.undertow.request - UT005035: Closing > > channel because of parse timeout for remote address > /0:0:0:0:0:0:0:1:51781 > > > > Is it safe to ignore it? Is there something I should pay attention to use > > exchange.getRequestReceiver().receiveFullBytes? > > > > Regards! > > Miere > > -- > > > > Miere Teixeira > > > > > > _______________________________________________ > > undertow-dev mailing list > > undertow-dev at lists.jboss.org > > https://lists.jboss.org/mailman/listinfo/undertow-dev > -- Miere Teixeira -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.jboss.org/pipermail/undertow-dev/attachments/20170118/c0248367/attachment.html From oliver at analyticspot.com Tue Jan 24 23:57:18 2017 From: oliver at analyticspot.com (Oliver Dain) Date: Wed, 25 Jan 2017 04:57:18 +0000 Subject: [undertow-dev] FormDataProcessor ending exchange prematurely Message-ID: I have some code for handling file uploads. It uses FormDataProcessor and tries to do everything asynchronously. I call "FormDataParser.parse" passing in another handler. I'll call that handler the OnFormDataAvailable. The OnFormDataAvailable handler checks to see if it's on the IO thread. If it is, it calls dispatch. Either way, once we're sure we're dispatched that handler calls yet another handler. What I've seen is that my OnFormDataAvailable handler (the one called by parse()) is not on the IO thread so it doesn't need to call dispatch. And yet, the exchange gets ended before the handler it calls is even close to complete. I've found a fix, but I don't understand why it's necessary. Specifically, if OnFormDataAvailable is not on the IO thread when its invoked it calls the 0-argument version of "HttpServerExchange.dispatch()" (which you've told me in another conversation shouldn't ever be necessary). If I do that, everything is fine. For completeness, here's the complete code: public class FormDataParsingHandler { private static final Logger log = LoggerFactory.getLogger(FormDataParsingHandler.class); private static final FormParserFactory formParserFactory = FormParserFactory.builder().build(); public static final AttachmentKey FORM_DATA_ATTACHMENT_KEY = AttachmentKey.create(FormData.class); /** * The only public method - this is what gets exposed as the HttpHandler. */ public CompletableFuture parseForm(HttpServerExchange exchange) { log.info("audio file upload request received."); FormDataParser parser = formParserFactory.createParser(exchange); if (parser == null) { log.warn("No parser found that can handle this content type. Headers were: {}", exchange.getRequestHeaders()); throw new UserVisibleException("No parser for the given content type.", ResponseCodes.BAD_REQUEST); } CompletableFuture toComplete = new CompletableFuture<>(); try { parser.parse(new OnFormDataAvailable(toComplete)); } catch (Exception e) { log.error("Error parsing form data:", e); throw wrapAsUnchecked(e); } exchange.addExchangeCompleteListener((ex, nextListener) -> { // Must close the parser so it can free any temporary files that were created. try { parser.close(); } catch (IOException e) { log.error("Error closing the FormDataParser. Request was handled successfully but temporary files may not " + "have been cleaned up.", e); } nextListener.proceed(); }); return toComplete; } // The FormDataParser calls an HttpHandler when it's complete so we add a silly handler here that does nothing but // complete this method's future when the form data is available. private static class OnFormDataAvailable implements HttpHandler { private final CompletableFuture toComplete; private OnFormDataAvailable(CompletableFuture toComplete) { this.toComplete = toComplete; } @Override public void handleRequest(HttpServerExchange exchange) throws Exception { // Before we complete the future we have to re-dispatch or we'll fall off the end of this method and Undertow // will complete the exchange on our behalf. FormData data = exchange.getAttachment(FormDataParser.FORM_DATA); if (exchange.isInIoThread()) { log.debug("Was on the IO thread. Re-dispatching."); exchange.dispatch(SameThreadExecutor.INSTANCE, () -> afterDistpach(data)); } else { // THIS THE MYSTERY LINE. WHY IS THIS NEEDED? exchange.dispatch(); afterDistpach(data); } } private void afterDistpach(FormData data) { if (data == null) { toComplete.completeExceptionally( new UserVisibleException("Parsing of data failed.", ResponseCodes.BAD_REQUEST)); } else { toComplete.complete(data); } } } } -- CTO, Analytic Spot 44 West Broadway #222 Eugene, OR 97401 analyticspot.com ? 425-296-6556 www.linkedin.com/in/oliverdain -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.jboss.org/pipermail/undertow-dev/attachments/20170125/a722f13b/attachment-0001.html From sdouglas at redhat.com Wed Jan 25 00:24:53 2017 From: sdouglas at redhat.com (Stuart Douglas) Date: Wed, 25 Jan 2017 16:24:53 +1100 Subject: [undertow-dev] FormDataProcessor ending exchange prematurely In-Reply-To: References: Message-ID: The handler is executed io.undertow.server.Connectors#executeRootHandler, which means that when the call stack returns the exchange will be ended. Conceptually this is similar to how dispatching to a thread pool works, when you call dispatch(HttpHandler) the exchange will be ended when the call stack returns, even though you are no longer on the IO thread (unless you call dispatch again). Stuart On Wed, Jan 25, 2017 at 3:57 PM, Oliver Dain wrote: > I have some code for handling file uploads. It uses FormDataProcessor and > tries to do everything asynchronously. I call "FormDataParser.parse" passing > in another handler. I'll call that handler the OnFormDataAvailable. The > OnFormDataAvailable handler checks to see if it's on the IO thread. If it > is, it calls dispatch. Either way, once we're sure we're dispatched that > handler calls yet another handler. > > What I've seen is that my OnFormDataAvailable handler (the one called by > parse()) is not on the IO thread so it doesn't need to call dispatch. And > yet, the exchange gets ended before the handler it calls is even close to > complete. > > I've found a fix, but I don't understand why it's necessary. Specifically, > if OnFormDataAvailable is not on the IO thread when its invoked it calls the > 0-argument version of "HttpServerExchange.dispatch()" (which you've told me > in another conversation shouldn't ever be necessary). If I do that, > everything is fine. > > For completeness, here's the complete code: > > public class FormDataParsingHandler { > private static final Logger log = > LoggerFactory.getLogger(FormDataParsingHandler.class); > private static final FormParserFactory formParserFactory = > FormParserFactory.builder().build(); > public static final AttachmentKey FORM_DATA_ATTACHMENT_KEY = > AttachmentKey.create(FormData.class); > > /** > * The only public method - this is what gets exposed as the HttpHandler. > */ > public CompletableFuture parseForm(HttpServerExchange exchange) > { > log.info("audio file upload request received."); > FormDataParser parser = formParserFactory.createParser(exchange); > if (parser == null) { > log.warn("No parser found that can handle this content type. Headers > were: {}", exchange.getRequestHeaders()); > throw new UserVisibleException("No parser for the given content > type.", ResponseCodes.BAD_REQUEST); > } > > CompletableFuture toComplete = new CompletableFuture<>(); > try { > parser.parse(new OnFormDataAvailable(toComplete)); > } catch (Exception e) { > log.error("Error parsing form data:", e); > throw wrapAsUnchecked(e); > } > > exchange.addExchangeCompleteListener((ex, nextListener) -> { > // Must close the parser so it can free any temporary files that were > created. > try { > parser.close(); > } catch (IOException e) { > log.error("Error closing the FormDataParser. Request was handled > successfully but temporary files may not " > + "have been cleaned up.", e); > } > nextListener.proceed(); > }); > > return toComplete; > } > > // The FormDataParser calls an HttpHandler when it's complete so we add a > silly handler here that does nothing but > // complete this method's future when the form data is available. > private static class OnFormDataAvailable implements HttpHandler { > private final CompletableFuture toComplete; > > private OnFormDataAvailable(CompletableFuture toComplete) { > this.toComplete = toComplete; > } > > @Override > public void handleRequest(HttpServerExchange exchange) throws Exception > { > // Before we complete the future we have to re-dispatch or we'll fall > off the end of this method and Undertow > // will complete the exchange on our behalf. > FormData data = exchange.getAttachment(FormDataParser.FORM_DATA); > if (exchange.isInIoThread()) { > log.debug("Was on the IO thread. Re-dispatching."); > exchange.dispatch(SameThreadExecutor.INSTANCE, () -> > afterDistpach(data)); > } else { > // THIS THE MYSTERY LINE. WHY IS THIS NEEDED? > exchange.dispatch(); > afterDistpach(data); > } > } > > private void afterDistpach(FormData data) { > if (data == null) { > toComplete.completeExceptionally( > new UserVisibleException("Parsing of data failed.", > ResponseCodes.BAD_REQUEST)); > } else { > toComplete.complete(data); > } > } > } > } > > -- > CTO, Analytic Spot > 44 West Broadway #222 > Eugene, OR 97401 > analyticspot.com ? 425-296-6556 > www.linkedin.com/in/oliverdain > > _______________________________________________ > undertow-dev mailing list > undertow-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/undertow-dev From bill at dartalley.com Wed Jan 25 08:53:30 2017 From: bill at dartalley.com (Bill O'Neil) Date: Wed, 25 Jan 2017 08:53:30 -0500 Subject: [undertow-dev] FormDataProcessor ending exchange prematurely In-Reply-To: References: Message-ID: Hey Stuart, your last response reminded me of of a question I had hopefully its not unrelated. I was curious how and when you should dispatch back to the IO thread. For example lets say we have a simple handler that does a SQL query that is composed with the AccessLogHandler. AccessLogHandler -> BlockingHandler -> CustomSqlHandler In this approach I believe the final access log statement will be logged from the worker thread not the initial IO thread. Is it possible / recommended to kick back to an IO thread once blocking is complete? AccessLogHandler -> BlockingHandler -> CustomSqlHandler -> DispatchBackToIOThread? This way the final logging of AccessLogHandler is handled in the IO thread. I'm not very familiar with the best ways to mix the nonblocking and blocking handlers. On Wed, Jan 25, 2017 at 12:24 AM, Stuart Douglas wrote: > The handler is executed > io.undertow.server.Connectors#executeRootHandler, which means that > when the call stack returns the exchange will be ended. > > Conceptually this is similar to how dispatching to a thread pool > works, when you call dispatch(HttpHandler) the exchange will be ended > when the call stack returns, even though you are no longer on the IO > thread (unless you call dispatch again). > > Stuart > > > On Wed, Jan 25, 2017 at 3:57 PM, Oliver Dain > wrote: > > I have some code for handling file uploads. It uses FormDataProcessor and > > tries to do everything asynchronously. I call "FormDataParser.parse" > passing > > in another handler. I'll call that handler the OnFormDataAvailable. The > > OnFormDataAvailable handler checks to see if it's on the IO thread. If it > > is, it calls dispatch. Either way, once we're sure we're dispatched that > > handler calls yet another handler. > > > > What I've seen is that my OnFormDataAvailable handler (the one called by > > parse()) is not on the IO thread so it doesn't need to call dispatch. And > > yet, the exchange gets ended before the handler it calls is even close to > > complete. > > > > I've found a fix, but I don't understand why it's necessary. > Specifically, > > if OnFormDataAvailable is not on the IO thread when its invoked it calls > the > > 0-argument version of "HttpServerExchange.dispatch()" (which you've > told me > > in another conversation shouldn't ever be necessary). If I do that, > > everything is fine. > > > > For completeness, here's the complete code: > > > > public class FormDataParsingHandler { > > private static final Logger log = > > LoggerFactory.getLogger(FormDataParsingHandler.class); > > private static final FormParserFactory formParserFactory = > > FormParserFactory.builder().build(); > > public static final AttachmentKey FORM_DATA_ATTACHMENT_KEY = > > AttachmentKey.create(FormData.class); > > > > /** > > * The only public method - this is what gets exposed as the > HttpHandler. > > */ > > public CompletableFuture parseForm(HttpServerExchange > exchange) > > { > > log.info("audio file upload request received."); > > FormDataParser parser = formParserFactory.createParser(exchange); > > if (parser == null) { > > log.warn("No parser found that can handle this content type. > Headers > > were: {}", exchange.getRequestHeaders()); > > throw new UserVisibleException("No parser for the given content > > type.", ResponseCodes.BAD_REQUEST); > > } > > > > CompletableFuture toComplete = new CompletableFuture<>(); > > try { > > parser.parse(new OnFormDataAvailable(toComplete)); > > } catch (Exception e) { > > log.error("Error parsing form data:", e); > > throw wrapAsUnchecked(e); > > } > > > > exchange.addExchangeCompleteListener((ex, nextListener) -> { > > // Must close the parser so it can free any temporary files that > were > > created. > > try { > > parser.close(); > > } catch (IOException e) { > > log.error("Error closing the FormDataParser. Request was handled > > successfully but temporary files may not " > > + "have been cleaned up.", e); > > } > > nextListener.proceed(); > > }); > > > > return toComplete; > > } > > > > // The FormDataParser calls an HttpHandler when it's complete so we > add a > > silly handler here that does nothing but > > // complete this method's future when the form data is available. > > private static class OnFormDataAvailable implements HttpHandler { > > private final CompletableFuture toComplete; > > > > private OnFormDataAvailable(CompletableFuture toComplete) > { > > this.toComplete = toComplete; > > } > > > > @Override > > public void handleRequest(HttpServerExchange exchange) throws > Exception > > { > > // Before we complete the future we have to re-dispatch or we'll > fall > > off the end of this method and Undertow > > // will complete the exchange on our behalf. > > FormData data = exchange.getAttachment(FormDataParser.FORM_DATA); > > if (exchange.isInIoThread()) { > > log.debug("Was on the IO thread. Re-dispatching."); > > exchange.dispatch(SameThreadExecutor.INSTANCE, () -> > > afterDistpach(data)); > > } else { > > // THIS THE MYSTERY LINE. WHY IS THIS NEEDED? > > exchange.dispatch(); > > afterDistpach(data); > > } > > } > > > > private void afterDistpach(FormData data) { > > if (data == null) { > > toComplete.completeExceptionally( > > new UserVisibleException("Parsing of data failed.", > > ResponseCodes.BAD_REQUEST)); > > } else { > > toComplete.complete(data); > > } > > } > > } > > } > > > > -- > > CTO, Analytic Spot > > 44 West Broadway #222 > > Eugene, OR 97401 > > analyticspot.com ? 425-296-6556 > > www.linkedin.com/in/oliverdain > > > > _______________________________________________ > > undertow-dev mailing list > > undertow-dev at lists.jboss.org > > https://lists.jboss.org/mailman/listinfo/undertow-dev > > _______________________________________________ > 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/20170125/13bc502c/attachment.html From sven at kubiak.me Wed Jan 25 09:58:35 2017 From: sven at kubiak.me (Sven Kubiak) Date: Wed, 25 Jan 2017 14:58:35 +0000 Subject: [undertow-dev] FormDataProcessor ending exchange prematurely In-Reply-To: References: , Message-ID: <1485356315871.31300@kubiak.me> Hi, sorry, for a kind of off-topic question, but as the FormDataProcessor is the topic here, I was wondering if there is already some kind of data sanitization? in the core form handling of Undertow. If not, which handler is a good starting point to hook into for this? Best regards, Sven ________________________________ Von: undertow-dev-bounces at lists.jboss.org im Auftrag von Bill O'Neil Gesendet: Mittwoch, 25. Januar 2017 14:53 An: Stuart Douglas Cc: Oliver Dain; undertow-dev at lists.jboss.org Betreff: Re: [undertow-dev] FormDataProcessor ending exchange prematurely Hey Stuart, your last response reminded me of of a question I had hopefully its not unrelated. I was curious how and when you should dispatch back to the IO thread. For example lets say we have a simple handler that does a SQL query that is composed with the AccessLogHandler. AccessLogHandler -> BlockingHandler -> CustomSqlHandler In this approach I believe the final access log statement will be logged from the worker thread not the initial IO thread. Is it possible / recommended to kick back to an IO thread once blocking is complete? AccessLogHandler -> BlockingHandler -> CustomSqlHandler -> DispatchBackToIOThread? This way the final logging of AccessLogHandler is handled in the IO thread. I'm not very familiar with the best ways to mix the nonblocking and blocking handlers. On Wed, Jan 25, 2017 at 12:24 AM, Stuart Douglas > wrote: The handler is executed io.undertow.server.Connectors#executeRootHandler, which means that when the call stack returns the exchange will be ended. Conceptually this is similar to how dispatching to a thread pool works, when you call dispatch(HttpHandler) the exchange will be ended when the call stack returns, even though you are no longer on the IO thread (unless you call dispatch again). Stuart On Wed, Jan 25, 2017 at 3:57 PM, Oliver Dain > wrote: > I have some code for handling file uploads. It uses FormDataProcessor and > tries to do everything asynchronously. I call "FormDataParser.parse" passing > in another handler. I'll call that handler the OnFormDataAvailable. The > OnFormDataAvailable handler checks to see if it's on the IO thread. If it > is, it calls dispatch. Either way, once we're sure we're dispatched that > handler calls yet another handler. > > What I've seen is that my OnFormDataAvailable handler (the one called by > parse()) is not on the IO thread so it doesn't need to call dispatch. And > yet, the exchange gets ended before the handler it calls is even close to > complete. > > I've found a fix, but I don't understand why it's necessary. Specifically, > if OnFormDataAvailable is not on the IO thread when its invoked it calls the > 0-argument version of "HttpServerExchange.dispatch()" (which you've told me > in another conversation shouldn't ever be necessary). If I do that, > everything is fine. > > For completeness, here's the complete code: > > public class FormDataParsingHandler { > private static final Logger log = > LoggerFactory.getLogger(FormDataParsingHandler.class); > private static final FormParserFactory formParserFactory = > FormParserFactory.builder().build(); > public static final AttachmentKey FORM_DATA_ATTACHMENT_KEY = > AttachmentKey.create(FormData.class); > > /** > * The only public method - this is what gets exposed as the HttpHandler. > */ > public CompletableFuture parseForm(HttpServerExchange exchange) > { > log.info("audio file upload request received."); > FormDataParser parser = formParserFactory.createParser(exchange); > if (parser == null) { > log.warn("No parser found that can handle this content type. Headers > were: {}", exchange.getRequestHeaders()); > throw new UserVisibleException("No parser for the given content > type.", ResponseCodes.BAD_REQUEST); > } > > CompletableFuture toComplete = new CompletableFuture<>(); > try { > parser.parse(new OnFormDataAvailable(toComplete)); > } catch (Exception e) { > log.error("Error parsing form data:", e); > throw wrapAsUnchecked(e); > } > > exchange.addExchangeCompleteListener((ex, nextListener) -> { > // Must close the parser so it can free any temporary files that were > created. > try { > parser.close(); > } catch (IOException e) { > log.error("Error closing the FormDataParser. Request was handled > successfully but temporary files may not " > + "have been cleaned up.", e); > } > nextListener.proceed(); > }); > > return toComplete; > } > > // The FormDataParser calls an HttpHandler when it's complete so we add a > silly handler here that does nothing but > // complete this method's future when the form data is available. > private static class OnFormDataAvailable implements HttpHandler { > private final CompletableFuture toComplete; > > private OnFormDataAvailable(CompletableFuture toComplete) { > this.toComplete = toComplete; > } > > @Override > public void handleRequest(HttpServerExchange exchange) throws Exception > { > // Before we complete the future we have to re-dispatch or we'll fall > off the end of this method and Undertow > // will complete the exchange on our behalf. > FormData data = exchange.getAttachment(FormDataParser.FORM_DATA); > if (exchange.isInIoThread()) { > log.debug("Was on the IO thread. Re-dispatching."); > exchange.dispatch(SameThreadExecutor.INSTANCE, () -> > afterDistpach(data)); > } else { > // THIS THE MYSTERY LINE. WHY IS THIS NEEDED? > exchange.dispatch(); > afterDistpach(data); > } > } > > private void afterDistpach(FormData data) { > if (data == null) { > toComplete.completeExceptionally( > new UserVisibleException("Parsing of data failed.", > ResponseCodes.BAD_REQUEST)); > } else { > toComplete.complete(data); > } > } > } > } > > -- > CTO, Analytic Spot > 44 West Broadway #222 > Eugene, OR 97401 > analyticspot.com ? 425-296-6556 > www.linkedin.com/in/oliverdain > > _______________________________________________ > undertow-dev mailing list > undertow-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/undertow-dev _______________________________________________ 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/20170125/3917481d/attachment-0001.html From mario.e.carbajal at gmail.com Thu Jan 26 14:50:25 2017 From: mario.e.carbajal at gmail.com (Mario Carbajal) Date: Thu, 26 Jan 2017 16:50:25 -0300 Subject: [undertow-dev] WebSockets static sendBinary methods.and PooledByteBuffers Message-ID: >From looking at the source it seems that the WebSockets.sendBinary methods that take ByteBuffer will take ownership of the buffer, meaning I shouldn't modify (or return it to a pool) after I pass it to these methods. Is this correct? Looking at sendInternal, the buffer passed is then wrapped in a dummy ImmediatePooledByteBuffer. I could make alternative versions of these sendBinary methods that take PooledByteBuffer. Allowing me to use pooled buffers. Since this functionality is missing it makes me think that there may be a reason why it shouldn't be done. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.jboss.org/pipermail/undertow-dev/attachments/20170126/53f3357a/attachment.html From sdouglas at redhat.com Thu Jan 26 18:36:45 2017 From: sdouglas at redhat.com (Stuart Douglas) Date: Fri, 27 Jan 2017 10:36:45 +1100 Subject: [undertow-dev] WebSockets static sendBinary methods.and PooledByteBuffers In-Reply-To: References: Message-ID: On Fri, Jan 27, 2017 at 6:50 AM, Mario Carbajal wrote: > From looking at the source it seems that the WebSockets.sendBinary methods > that take ByteBuffer will take ownership of the buffer, meaning I shouldn't > modify (or return it to a pool) after I pass it to these methods. Is this > correct? Yes, you need to wait for the callback to be called before you can do anything with it. > > Looking at sendInternal, the buffer passed is then wrapped in a dummy > ImmediatePooledByteBuffer. I could make alternative versions of these > sendBinary methods that take PooledByteBuffer. Allowing me to use pooled > buffers. Sounds good. > > Since this functionality is missing it makes me think that there may be a > reason why it shouldn't be done. Mostly because nobody has asked for it yet. Stuart > > _______________________________________________ > undertow-dev mailing list > undertow-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/undertow-dev From sdouglas at redhat.com Thu Jan 26 19:10:59 2017 From: sdouglas at redhat.com (Stuart Douglas) Date: Fri, 27 Jan 2017 11:10:59 +1100 Subject: [undertow-dev] FormDataProcessor ending exchange prematurely In-Reply-To: References: Message-ID: In general there is never any real need to dispatch back to an IO thread, although if you perform any non blocking IO ownership of the exchange can end up back in the IO thread when the operation is complete. Stuart On Thu, Jan 26, 2017 at 12:53 AM, Bill O'Neil wrote: > Hey Stuart, your last response reminded me of of a question I had hopefully > its not unrelated. I was curious how and when you should dispatch back to > the IO thread. For example lets say we have a simple handler that does a SQL > query that is composed with the AccessLogHandler. > > AccessLogHandler -> BlockingHandler -> CustomSqlHandler In this approach I > believe the final access log statement will be logged from the worker thread > not the initial IO thread. > > Is it possible / recommended to kick back to an IO thread once blocking is > complete? > > AccessLogHandler -> BlockingHandler -> CustomSqlHandler -> > DispatchBackToIOThread? This way the final logging of AccessLogHandler is > handled in the IO thread. > > I'm not very familiar with the best ways to mix the nonblocking and blocking > handlers. > > > > On Wed, Jan 25, 2017 at 12:24 AM, Stuart Douglas > wrote: >> >> The handler is executed >> io.undertow.server.Connectors#executeRootHandler, which means that >> when the call stack returns the exchange will be ended. >> >> Conceptually this is similar to how dispatching to a thread pool >> works, when you call dispatch(HttpHandler) the exchange will be ended >> when the call stack returns, even though you are no longer on the IO >> thread (unless you call dispatch again). >> >> Stuart >> >> >> On Wed, Jan 25, 2017 at 3:57 PM, Oliver Dain >> wrote: >> > I have some code for handling file uploads. It uses FormDataProcessor >> > and >> > tries to do everything asynchronously. I call "FormDataParser.parse" >> > passing >> > in another handler. I'll call that handler the OnFormDataAvailable. The >> > OnFormDataAvailable handler checks to see if it's on the IO thread. If >> > it >> > is, it calls dispatch. Either way, once we're sure we're dispatched that >> > handler calls yet another handler. >> > >> > What I've seen is that my OnFormDataAvailable handler (the one called by >> > parse()) is not on the IO thread so it doesn't need to call dispatch. >> > And >> > yet, the exchange gets ended before the handler it calls is even close >> > to >> > complete. >> > >> > I've found a fix, but I don't understand why it's necessary. >> > Specifically, >> > if OnFormDataAvailable is not on the IO thread when its invoked it calls >> > the >> > 0-argument version of "HttpServerExchange.dispatch()" (which you've told >> > me >> > in another conversation shouldn't ever be necessary). If I do that, >> > everything is fine. >> > >> > For completeness, here's the complete code: >> > >> > public class FormDataParsingHandler { >> > private static final Logger log = >> > LoggerFactory.getLogger(FormDataParsingHandler.class); >> > private static final FormParserFactory formParserFactory = >> > FormParserFactory.builder().build(); >> > public static final AttachmentKey FORM_DATA_ATTACHMENT_KEY = >> > AttachmentKey.create(FormData.class); >> > >> > /** >> > * The only public method - this is what gets exposed as the >> > HttpHandler. >> > */ >> > public CompletableFuture parseForm(HttpServerExchange >> > exchange) >> > { >> > log.info("audio file upload request received."); >> > FormDataParser parser = formParserFactory.createParser(exchange); >> > if (parser == null) { >> > log.warn("No parser found that can handle this content type. >> > Headers >> > were: {}", exchange.getRequestHeaders()); >> > throw new UserVisibleException("No parser for the given content >> > type.", ResponseCodes.BAD_REQUEST); >> > } >> > >> > CompletableFuture toComplete = new CompletableFuture<>(); >> > try { >> > parser.parse(new OnFormDataAvailable(toComplete)); >> > } catch (Exception e) { >> > log.error("Error parsing form data:", e); >> > throw wrapAsUnchecked(e); >> > } >> > >> > exchange.addExchangeCompleteListener((ex, nextListener) -> { >> > // Must close the parser so it can free any temporary files that >> > were >> > created. >> > try { >> > parser.close(); >> > } catch (IOException e) { >> > log.error("Error closing the FormDataParser. Request was handled >> > successfully but temporary files may not " >> > + "have been cleaned up.", e); >> > } >> > nextListener.proceed(); >> > }); >> > >> > return toComplete; >> > } >> > >> > // The FormDataParser calls an HttpHandler when it's complete so we >> > add a >> > silly handler here that does nothing but >> > // complete this method's future when the form data is available. >> > private static class OnFormDataAvailable implements HttpHandler { >> > private final CompletableFuture toComplete; >> > >> > private OnFormDataAvailable(CompletableFuture toComplete) >> > { >> > this.toComplete = toComplete; >> > } >> > >> > @Override >> > public void handleRequest(HttpServerExchange exchange) throws >> > Exception >> > { >> > // Before we complete the future we have to re-dispatch or we'll >> > fall >> > off the end of this method and Undertow >> > // will complete the exchange on our behalf. >> > FormData data = exchange.getAttachment(FormDataParser.FORM_DATA); >> > if (exchange.isInIoThread()) { >> > log.debug("Was on the IO thread. Re-dispatching."); >> > exchange.dispatch(SameThreadExecutor.INSTANCE, () -> >> > afterDistpach(data)); >> > } else { >> > // THIS THE MYSTERY LINE. WHY IS THIS NEEDED? >> > exchange.dispatch(); >> > afterDistpach(data); >> > } >> > } >> > >> > private void afterDistpach(FormData data) { >> > if (data == null) { >> > toComplete.completeExceptionally( >> > new UserVisibleException("Parsing of data failed.", >> > ResponseCodes.BAD_REQUEST)); >> > } else { >> > toComplete.complete(data); >> > } >> > } >> > } >> > } >> > >> > -- >> > CTO, Analytic Spot >> > 44 West Broadway #222 >> > Eugene, OR 97401 >> > analyticspot.com ? 425-296-6556 >> > www.linkedin.com/in/oliverdain >> > >> > _______________________________________________ >> > undertow-dev mailing list >> > undertow-dev at lists.jboss.org >> > https://lists.jboss.org/mailman/listinfo/undertow-dev >> >> _______________________________________________ >> undertow-dev mailing list >> undertow-dev at lists.jboss.org >> https://lists.jboss.org/mailman/listinfo/undertow-dev > > From oliver at analyticspot.com Thu Jan 26 20:10:05 2017 From: oliver at analyticspot.com (Oliver Dain) Date: Fri, 27 Jan 2017 01:10:05 +0000 Subject: [undertow-dev] FormDataProcessor ending exchange prematurely In-Reply-To: References: Message-ID: Along these lines, I've been trying to figure out a reliable way to tell if a call to dispatch is necessary. Suppose I have a handler that can be called alone or could be nested inside another handler. My handler is going to do something async so I need to make sure it's been dispatched. Since it's about to do something very fast and async there's no need to move that work to another thread, I just want to run it locally so **if** it needs dispatching I'd call "dispatch(SameThreadExecutor.INSTANCE, ::doSomeStuff)". The handler wrapping this might do the same (dispatch, but right back to the IO thread). Thus, when my handler gets called it **might** have already been dispatched but it's not sure. Calling "Exchange.isInIoThread()" isn't reliable as the wrapping handler may have dispatched via SameThreadExecutor so being on the IO thread does not mean a dispatch in needed. OTOH, as I understand it (not sure, please correct me if I'm wrong) "isDispatched" isn't generally reliable as that gets unset as soon as you've left the IO thread so if the wrapper dispatched using any executor besides SameThreadExecutor my handler doesn't need to dispatch but isDispatched will be false. So, I think what is reliable is that you need to dispatch if and only if "isInIoThread() && !isDispatched()". Is that correct? On Thu, Jan 26, 2017 at 4:10 PM Stuart Douglas wrote: > In general there is never any real need to dispatch back to an IO > thread, although if you perform any non blocking IO ownership of the > exchange can end up back in the IO thread when the operation is > complete. > > Stuart > > On Thu, Jan 26, 2017 at 12:53 AM, Bill O'Neil wrote: > > Hey Stuart, your last response reminded me of of a question I had > hopefully > > its not unrelated. I was curious how and when you should dispatch back to > > the IO thread. For example lets say we have a simple handler that does a > SQL > > query that is composed with the AccessLogHandler. > > > > AccessLogHandler -> BlockingHandler -> CustomSqlHandler In this approach > I > > believe the final access log statement will be logged from the worker > thread > > not the initial IO thread. > > > > Is it possible / recommended to kick back to an IO thread once blocking > is > > complete? > > > > AccessLogHandler -> BlockingHandler -> CustomSqlHandler -> > > DispatchBackToIOThread? This way the final logging of AccessLogHandler is > > handled in the IO thread. > > > > I'm not very familiar with the best ways to mix the nonblocking and > blocking > > handlers. > > > > > > > > On Wed, Jan 25, 2017 at 12:24 AM, Stuart Douglas > > wrote: > >> > >> The handler is executed > >> io.undertow.server.Connectors#executeRootHandler, which means that > >> when the call stack returns the exchange will be ended. > >> > >> Conceptually this is similar to how dispatching to a thread pool > >> works, when you call dispatch(HttpHandler) the exchange will be ended > >> when the call stack returns, even though you are no longer on the IO > >> thread (unless you call dispatch again). > >> > >> Stuart > >> > >> > >> On Wed, Jan 25, 2017 at 3:57 PM, Oliver Dain > >> wrote: > >> > I have some code for handling file uploads. It uses FormDataProcessor > >> > and > >> > tries to do everything asynchronously. I call "FormDataParser.parse" > >> > passing > >> > in another handler. I'll call that handler the OnFormDataAvailable. > The > >> > OnFormDataAvailable handler checks to see if it's on the IO thread. If > >> > it > >> > is, it calls dispatch. Either way, once we're sure we're dispatched > that > >> > handler calls yet another handler. > >> > > >> > What I've seen is that my OnFormDataAvailable handler (the one called > by > >> > parse()) is not on the IO thread so it doesn't need to call dispatch. > >> > And > >> > yet, the exchange gets ended before the handler it calls is even close > >> > to > >> > complete. > >> > > >> > I've found a fix, but I don't understand why it's necessary. > >> > Specifically, > >> > if OnFormDataAvailable is not on the IO thread when its invoked it > calls > >> > the > >> > 0-argument version of "HttpServerExchange.dispatch()" (which you've > told > >> > me > >> > in another conversation shouldn't ever be necessary). If I do that, > >> > everything is fine. > >> > > >> > For completeness, here's the complete code: > >> > > >> > public class FormDataParsingHandler { > >> > private static final Logger log = > >> > LoggerFactory.getLogger(FormDataParsingHandler.class); > >> > private static final FormParserFactory formParserFactory = > >> > FormParserFactory.builder().build(); > >> > public static final AttachmentKey > FORM_DATA_ATTACHMENT_KEY = > >> > AttachmentKey.create(FormData.class); > >> > > >> > /** > >> > * The only public method - this is what gets exposed as the > >> > HttpHandler. > >> > */ > >> > public CompletableFuture parseForm(HttpServerExchange > >> > exchange) > >> > { > >> > log.info("audio file upload request received."); > >> > FormDataParser parser = formParserFactory.createParser(exchange); > >> > if (parser == null) { > >> > log.warn("No parser found that can handle this content type. > >> > Headers > >> > were: {}", exchange.getRequestHeaders()); > >> > throw new UserVisibleException("No parser for the given content > >> > type.", ResponseCodes.BAD_REQUEST); > >> > } > >> > > >> > CompletableFuture toComplete = new > CompletableFuture<>(); > >> > try { > >> > parser.parse(new OnFormDataAvailable(toComplete)); > >> > } catch (Exception e) { > >> > log.error("Error parsing form data:", e); > >> > throw wrapAsUnchecked(e); > >> > } > >> > > >> > exchange.addExchangeCompleteListener((ex, nextListener) -> { > >> > // Must close the parser so it can free any temporary files that > >> > were > >> > created. > >> > try { > >> > parser.close(); > >> > } catch (IOException e) { > >> > log.error("Error closing the FormDataParser. Request was > handled > >> > successfully but temporary files may not " > >> > + "have been cleaned up.", e); > >> > } > >> > nextListener.proceed(); > >> > }); > >> > > >> > return toComplete; > >> > } > >> > > >> > // The FormDataParser calls an HttpHandler when it's complete so we > >> > add a > >> > silly handler here that does nothing but > >> > // complete this method's future when the form data is available. > >> > private static class OnFormDataAvailable implements HttpHandler { > >> > private final CompletableFuture toComplete; > >> > > >> > private OnFormDataAvailable(CompletableFuture > toComplete) > >> > { > >> > this.toComplete = toComplete; > >> > } > >> > > >> > @Override > >> > public void handleRequest(HttpServerExchange exchange) throws > >> > Exception > >> > { > >> > // Before we complete the future we have to re-dispatch or we'll > >> > fall > >> > off the end of this method and Undertow > >> > // will complete the exchange on our behalf. > >> > FormData data = > exchange.getAttachment(FormDataParser.FORM_DATA); > >> > if (exchange.isInIoThread()) { > >> > log.debug("Was on the IO thread. Re-dispatching."); > >> > exchange.dispatch(SameThreadExecutor.INSTANCE, () -> > >> > afterDistpach(data)); > >> > } else { > >> > // THIS THE MYSTERY LINE. WHY IS THIS NEEDED? > >> > exchange.dispatch(); > >> > afterDistpach(data); > >> > } > >> > } > >> > > >> > private void afterDistpach(FormData data) { > >> > if (data == null) { > >> > toComplete.completeExceptionally( > >> > new UserVisibleException("Parsing of data failed.", > >> > ResponseCodes.BAD_REQUEST)); > >> > } else { > >> > toComplete.complete(data); > >> > } > >> > } > >> > } > >> > } > >> > > >> > -- > >> > CTO, Analytic Spot > >> > 44 West Broadway #222 > >> > Eugene, OR 97401 > >> > analyticspot.com ? 425-296-6556 <(425)%20296-6556> > >> > www.linkedin.com/in/oliverdain > >> > > >> > _______________________________________________ > >> > undertow-dev mailing list > >> > undertow-dev at lists.jboss.org > >> > https://lists.jboss.org/mailman/listinfo/undertow-dev > >> > >> _______________________________________________ > >> undertow-dev mailing list > >> undertow-dev at lists.jboss.org > >> https://lists.jboss.org/mailman/listinfo/undertow-dev > > > > > -- CTO, Analytic Spot 44 West Broadway #222 Eugene, OR 97401 analyticspot.com ? 425-296-6556 www.linkedin.com/in/oliverdain -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.jboss.org/pipermail/undertow-dev/attachments/20170127/2d02189f/attachment-0001.html From sdouglas at redhat.com Thu Jan 26 21:09:37 2017 From: sdouglas at redhat.com (Stuart Douglas) Date: Fri, 27 Jan 2017 13:09:37 +1100 Subject: [undertow-dev] FormDataProcessor ending exchange prematurely In-Reply-To: References: Message-ID: On Fri, Jan 27, 2017 at 12:10 PM, Oliver Dain wrote: > Along these lines, I've been trying to figure out a reliable way to tell if > a call to dispatch is necessary. Suppose I have a handler that can be called > alone or could be nested inside another handler. My handler is going to do > something async so I need to make sure it's been dispatched. Since it's > about to do something very fast and async there's no need to move that work > to another thread, I just want to run it locally so **if** it needs > dispatching I'd call "dispatch(SameThreadExecutor.INSTANCE, ::doSomeStuff)". > The handler wrapping this might do the same (dispatch, but right back to the > IO thread). Thus, when my handler gets called it **might** have already been > dispatched but it's not sure. If the exchange has already been dispatched (i.e. it is no running inside Connectors.executeRootHandler) then calling dispatch(SameThreadExecutor.INSTANCE, ::doSomeStuff) is very fast, it will basically just execute the task in the provided executor (in general any SameThreadExecutor dispatch is very fast, the cost of a dispatch is from dispatching to a real executor). > > Calling "Exchange.isInIoThread()" isn't reliable as the wrapping handler may > have dispatched via SameThreadExecutor so being on the IO thread does not > mean a dispatch in needed. OTOH, as I understand it (not sure, please > correct me if I'm wrong) "isDispatched" isn't generally reliable as that > gets unset as soon as you've left the IO thread so if the wrapper dispatched > using any executor besides SameThreadExecutor my handler doesn't need to > dispatch but isDispatched will be false. > > So, I think what is reliable is that you need to dispatch if and only if > "isInIoThread() && !isDispatched()". Is that correct? If you are going to use SameThreadExecutor you might as well just always dispatch, it should not make any difference performance wise. Stuart > > On Thu, Jan 26, 2017 at 4:10 PM Stuart Douglas wrote: >> >> In general there is never any real need to dispatch back to an IO >> thread, although if you perform any non blocking IO ownership of the >> exchange can end up back in the IO thread when the operation is >> complete. >> >> Stuart >> >> On Thu, Jan 26, 2017 at 12:53 AM, Bill O'Neil wrote: >> > Hey Stuart, your last response reminded me of of a question I had >> > hopefully >> > its not unrelated. I was curious how and when you should dispatch back >> > to >> > the IO thread. For example lets say we have a simple handler that does a >> > SQL >> > query that is composed with the AccessLogHandler. >> > >> > AccessLogHandler -> BlockingHandler -> CustomSqlHandler In this approach >> > I >> > believe the final access log statement will be logged from the worker >> > thread >> > not the initial IO thread. >> > >> > Is it possible / recommended to kick back to an IO thread once blocking >> > is >> > complete? >> > >> > AccessLogHandler -> BlockingHandler -> CustomSqlHandler -> >> > DispatchBackToIOThread? This way the final logging of AccessLogHandler >> > is >> > handled in the IO thread. >> > >> > I'm not very familiar with the best ways to mix the nonblocking and >> > blocking >> > handlers. >> > >> > >> > >> > On Wed, Jan 25, 2017 at 12:24 AM, Stuart Douglas >> > wrote: >> >> >> >> The handler is executed >> >> io.undertow.server.Connectors#executeRootHandler, which means that >> >> when the call stack returns the exchange will be ended. >> >> >> >> Conceptually this is similar to how dispatching to a thread pool >> >> works, when you call dispatch(HttpHandler) the exchange will be ended >> >> when the call stack returns, even though you are no longer on the IO >> >> thread (unless you call dispatch again). >> >> >> >> Stuart >> >> >> >> >> >> On Wed, Jan 25, 2017 at 3:57 PM, Oliver Dain >> >> wrote: >> >> > I have some code for handling file uploads. It uses FormDataProcessor >> >> > and >> >> > tries to do everything asynchronously. I call "FormDataParser.parse" >> >> > passing >> >> > in another handler. I'll call that handler the OnFormDataAvailable. >> >> > The >> >> > OnFormDataAvailable handler checks to see if it's on the IO thread. >> >> > If >> >> > it >> >> > is, it calls dispatch. Either way, once we're sure we're dispatched >> >> > that >> >> > handler calls yet another handler. >> >> > >> >> > What I've seen is that my OnFormDataAvailable handler (the one called >> >> > by >> >> > parse()) is not on the IO thread so it doesn't need to call dispatch. >> >> > And >> >> > yet, the exchange gets ended before the handler it calls is even >> >> > close >> >> > to >> >> > complete. >> >> > >> >> > I've found a fix, but I don't understand why it's necessary. >> >> > Specifically, >> >> > if OnFormDataAvailable is not on the IO thread when its invoked it >> >> > calls >> >> > the >> >> > 0-argument version of "HttpServerExchange.dispatch()" (which you've >> >> > told >> >> > me >> >> > in another conversation shouldn't ever be necessary). If I do that, >> >> > everything is fine. >> >> > >> >> > For completeness, here's the complete code: >> >> > >> >> > public class FormDataParsingHandler { >> >> > private static final Logger log = >> >> > LoggerFactory.getLogger(FormDataParsingHandler.class); >> >> > private static final FormParserFactory formParserFactory = >> >> > FormParserFactory.builder().build(); >> >> > public static final AttachmentKey >> >> > FORM_DATA_ATTACHMENT_KEY = >> >> > AttachmentKey.create(FormData.class); >> >> > >> >> > /** >> >> > * The only public method - this is what gets exposed as the >> >> > HttpHandler. >> >> > */ >> >> > public CompletableFuture parseForm(HttpServerExchange >> >> > exchange) >> >> > { >> >> > log.info("audio file upload request received."); >> >> > FormDataParser parser = formParserFactory.createParser(exchange); >> >> > if (parser == null) { >> >> > log.warn("No parser found that can handle this content type. >> >> > Headers >> >> > were: {}", exchange.getRequestHeaders()); >> >> > throw new UserVisibleException("No parser for the given content >> >> > type.", ResponseCodes.BAD_REQUEST); >> >> > } >> >> > >> >> > CompletableFuture toComplete = new >> >> > CompletableFuture<>(); >> >> > try { >> >> > parser.parse(new OnFormDataAvailable(toComplete)); >> >> > } catch (Exception e) { >> >> > log.error("Error parsing form data:", e); >> >> > throw wrapAsUnchecked(e); >> >> > } >> >> > >> >> > exchange.addExchangeCompleteListener((ex, nextListener) -> { >> >> > // Must close the parser so it can free any temporary files >> >> > that >> >> > were >> >> > created. >> >> > try { >> >> > parser.close(); >> >> > } catch (IOException e) { >> >> > log.error("Error closing the FormDataParser. Request was >> >> > handled >> >> > successfully but temporary files may not " >> >> > + "have been cleaned up.", e); >> >> > } >> >> > nextListener.proceed(); >> >> > }); >> >> > >> >> > return toComplete; >> >> > } >> >> > >> >> > // The FormDataParser calls an HttpHandler when it's complete so we >> >> > add a >> >> > silly handler here that does nothing but >> >> > // complete this method's future when the form data is available. >> >> > private static class OnFormDataAvailable implements HttpHandler { >> >> > private final CompletableFuture toComplete; >> >> > >> >> > private OnFormDataAvailable(CompletableFuture >> >> > toComplete) >> >> > { >> >> > this.toComplete = toComplete; >> >> > } >> >> > >> >> > @Override >> >> > public void handleRequest(HttpServerExchange exchange) throws >> >> > Exception >> >> > { >> >> > // Before we complete the future we have to re-dispatch or >> >> > we'll >> >> > fall >> >> > off the end of this method and Undertow >> >> > // will complete the exchange on our behalf. >> >> > FormData data = >> >> > exchange.getAttachment(FormDataParser.FORM_DATA); >> >> > if (exchange.isInIoThread()) { >> >> > log.debug("Was on the IO thread. Re-dispatching."); >> >> > exchange.dispatch(SameThreadExecutor.INSTANCE, () -> >> >> > afterDistpach(data)); >> >> > } else { >> >> > // THIS THE MYSTERY LINE. WHY IS THIS NEEDED? >> >> > exchange.dispatch(); >> >> > afterDistpach(data); >> >> > } >> >> > } >> >> > >> >> > private void afterDistpach(FormData data) { >> >> > if (data == null) { >> >> > toComplete.completeExceptionally( >> >> > new UserVisibleException("Parsing of data failed.", >> >> > ResponseCodes.BAD_REQUEST)); >> >> > } else { >> >> > toComplete.complete(data); >> >> > } >> >> > } >> >> > } >> >> > } >> >> > >> >> > -- >> >> > CTO, Analytic Spot >> >> > 44 West Broadway #222 >> >> > Eugene, OR 97401 >> >> > analyticspot.com ? 425-296-6556 >> >> > www.linkedin.com/in/oliverdain >> >> > >> >> > _______________________________________________ >> >> > undertow-dev mailing list >> >> > undertow-dev at lists.jboss.org >> >> > https://lists.jboss.org/mailman/listinfo/undertow-dev >> >> >> >> _______________________________________________ >> >> undertow-dev mailing list >> >> undertow-dev at lists.jboss.org >> >> https://lists.jboss.org/mailman/listinfo/undertow-dev >> > >> > > > -- > CTO, Analytic Spot > 44 West Broadway #222 > Eugene, OR 97401 > analyticspot.com ? 425-296-6556 > www.linkedin.com/in/oliverdain From thomas.darimont at googlemail.com Mon Jan 30 05:34:16 2017 From: thomas.darimont at googlemail.com (Thomas Darimont) Date: Mon, 30 Jan 2017 11:34:16 +0100 Subject: [undertow-dev] Return HTTP Status 503 (Service Unvailable) until Web Application is available. Message-ID: Hello group, (coss-post from keycloak-user Mailing List) the undertow servlet-container is started pretty early during the startup of the wildfly application server. However the initialization of the keycloak server application might take a while to complete. Within this period requests that are sent to the keycloak endpoints result in responses with HTTP Status Code 404. Is it possible to configure undertow to return a HTTP Status Code 503 (Service Unvailable) until the keycloak application startup has completed? This would ease configuring load-balancers and to avoid showing a file not found to users during server restarts. Cheers, Thomas -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.jboss.org/pipermail/undertow-dev/attachments/20170130/9bffab2f/attachment.html From sdouglas at redhat.com Mon Jan 30 16:09:41 2017 From: sdouglas at redhat.com (Stuart Douglas) Date: Tue, 31 Jan 2017 08:09:41 +1100 Subject: [undertow-dev] Return HTTP Status 503 (Service Unvailable) until Web Application is available. In-Reply-To: References: Message-ID: You can add the default-response-code attribute in the host element of the undertow subsystem to make it return 503 by default. Stuart On Mon, Jan 30, 2017 at 9:34 PM, Thomas Darimont wrote: > Hello group, > > (coss-post from keycloak-user Mailing List) > > the undertow servlet-container is started pretty early during the startup of > the > wildfly application server. However the initialization of the keycloak > server > application might take a while to complete. Within this period requests that > are > sent to the keycloak endpoints result in responses with HTTP Status Code > 404. > > Is it possible to configure undertow to return a HTTP Status Code 503 > (Service Unvailable) > until the keycloak application startup has completed? > > This would ease configuring load-balancers and to avoid showing a file not > found > to users during server restarts. > > Cheers, > Thomas > > _______________________________________________ > undertow-dev mailing list > undertow-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/undertow-dev From thomas.darimont at googlemail.com Mon Jan 30 16:44:07 2017 From: thomas.darimont at googlemail.com (Thomas Darimont) Date: Mon, 30 Jan 2017 22:44:07 +0100 Subject: [undertow-dev] Return HTTP Status 503 (Service Unvailable) until Web Application is available. In-Reply-To: References: Message-ID: Hi Stuart, thanks for the reply - I got a similar tip on the keycloak-user list however if I configure the default-response-code=503 on the (single) host element of the undertow subsystem in Wildfly (10.1.0) and restart the server then I get a 404 but never a 503 when I access paths of an web app (keycloak) that is not fully initialized yet. Seems that I'm seeing the same behaviour as those folks: https://developer.jboss.org/thread/257526 Is there anything else that one needs to configure to make this work? In the meantime I played a bit with alternative approaches e.g.: https://github.com/thomasdarimont/undertow-extensions Cheers, Thomas 2017-01-30 22:09 GMT+01:00 Stuart Douglas : > You can add the default-response-code attribute in the host element of > the undertow subsystem to make it return 503 by default. > > Stuart > > On Mon, Jan 30, 2017 at 9:34 PM, Thomas Darimont > wrote: > > Hello group, > > > > (coss-post from keycloak-user Mailing List) > > > > the undertow servlet-container is started pretty early during the > startup of > > the > > wildfly application server. However the initialization of the keycloak > > server > > application might take a while to complete. Within this period requests > that > > are > > sent to the keycloak endpoints result in responses with HTTP Status Code > > 404. > > > > Is it possible to configure undertow to return a HTTP Status Code 503 > > (Service Unvailable) > > until the keycloak application startup has completed? > > > > This would ease configuring load-balancers and to avoid showing a file > not > > found > > to users during server restarts. > > > > Cheers, > > Thomas > > > > _______________________________________________ > > 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/20170130/5540d12d/attachment.html From thomas.darimont at googlemail.com Tue Jan 31 06:18:55 2017 From: thomas.darimont at googlemail.com (Thomas Darimont) Date: Tue, 31 Jan 2017 12:18:55 +0100 Subject: [undertow-dev] Return HTTP Status 503 (Service Unvailable) until Web Application is available. In-Reply-To: References: Message-ID: Quick update In order to see the 503 Status code specified in the default-response-code attribute on the host-element I had to remove the welcome-content filter by omitting the element. However even with that config I see the following sequence from a repeated curl sequence: watch -n 2 curl -I http://localhost:8080/auth/ Server not started : Connection Refused... Server Started... : HTTP/1.1 404 Not Found Begin Web App Deployment (Keycloak): HTTP/1.1 503 Service Unvailable Web App Deployed : HTTP/1.1 200 OK My example configuration Cheers, Thomas 2017-01-30 22:44 GMT+01:00 Thomas Darimont : > Hi Stuart, > > thanks for the reply - I got a similar tip on the keycloak-user list > however if I configure the default-response-code=503 > on the (single) host element of the undertow subsystem in Wildfly (10.1.0) > and restart the server then I get a > 404 but never a 503 when I access paths of an web app (keycloak) that is > not fully initialized yet. > > Seems that I'm seeing the same behaviour as those folks: > https://developer.jboss.org/thread/257526 > > Is there anything else that one needs to configure to make this work? > > In the meantime I played a bit with alternative approaches e.g.: > https://github.com/thomasdarimont/undertow-extensions > > Cheers, > Thomas > > 2017-01-30 22:09 GMT+01:00 Stuart Douglas : > >> You can add the default-response-code attribute in the host element of >> the undertow subsystem to make it return 503 by default. >> >> Stuart >> >> On Mon, Jan 30, 2017 at 9:34 PM, Thomas Darimont >> wrote: >> > Hello group, >> > >> > (coss-post from keycloak-user Mailing List) >> > >> > the undertow servlet-container is started pretty early during the >> startup of >> > the >> > wildfly application server. However the initialization of the keycloak >> > server >> > application might take a while to complete. Within this period requests >> that >> > are >> > sent to the keycloak endpoints result in responses with HTTP Status Code >> > 404. >> > >> > Is it possible to configure undertow to return a HTTP Status Code 503 >> > (Service Unvailable) >> > until the keycloak application startup has completed? >> > >> > This would ease configuring load-balancers and to avoid showing a file >> not >> > found >> > to users during server restarts. >> > >> > Cheers, >> > Thomas >> > >> > _______________________________________________ >> > 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/20170131/1296e990/attachment-0001.html