Resteasy is using org.jboss.resteasy.plugins.server.servlet.HttpServlet30Dispatcher in processing @Suspended. We use it in test cases here, ./testsuite/integration-tests/src/test/resources/org/jboss/resteasy/test/asynch ----- Original Message -----From: "Steven Schlansker" <sschlansker@opentable.com> To: resteasy-dev@lists.jboss.org Sent: Tuesday, October 11, 2016 7:16:29 PM Subject: Re: [resteasy-dev] RESTEasy asynchronous processing with @Suspended -- actually synchronous? Hi again, I was somewhat disappointed to not get an answer here, but I did a fair amount more digging, and managed to find Filter30Dispatcher (which just moved recently for upcoming 3.1.0) Unfortunately then I found that the documentation does not mention this class at all, but at least it exists! (at least not on http://docs.jboss.org/resteasy/docs/3.0.19.Final/userguide/html_single/index.html ) So far it seems to work well. Better than FilterDispatcher, at least :) Let me know if there's any gotchas or other bits that I've missed. Best, StevenOn Oct 7, 2016, at 1:21 PM, Steven Schlansker <sschlansker@opentable.com> wrote: [ apologies for the rampant cross-posting, it looks like I might have been sending this to old mailing lists, and getting lost in the void? ] Hello resteasy-dev, I am trying to use the new JAX-RS 2.0 @Suspended AsyncResponse mechanism to write a service that expects many idling connections (awaiting an event via long-poll), and therefore seems like a good candidate for asynchronous responses, so as not to use a large number of waiting threads. The resource code is very simple: @GET @Produces(MediaType.APPLICATION_JSON) public void watchForChanges( @Suspended AsyncResponse asyncResponse, @QueryParam("since") long since) { controller.watchForChanges(since, asyncResponse::resume); } The intent is that watchForChanges places the (inferred) Consumer<ResponseObject> on a queue, and returns immediately. Later on a background thread comes by and completes the request. However, when testing with say 20 clients, it sure looks like the end result is still a thread per request model: "qtp1718322084-43" - Thread t@43 java.lang.Thread.State: WAITING at sun.misc.Unsafe.park(Native Method) - parking to wait for <3537ebd5> (a java.util.concurrent.CountDownLatch$Sync) at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836) at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:997) at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1304) at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:231) at org.jboss.resteasy.core.SynchronousExecutionContext$SynchronousAsynchronousResponse.initialRequestThreadFinished(SynchronousExecutionContext.java:127) at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:411) at org.jboss.resteasy.core.SynchronousDispatcher.invokePropagateNotFound(SynchronousDispatcher.java:247) at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:225) at org.jboss.resteasy.plugins.server.servlet.FilterDispatcher.doFilter(FilterDispatcher.java:62) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1676) <snip Jetty handler / filter chain> at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:319) at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:253) at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:273) at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:95) at org.eclipse.jetty.io.SelectChannelEndPoint$2.run(SelectChannelEndPoint.java:93) at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.executeProduceConsume(ExecuteProduceConsume.java:303) at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceConsume(ExecuteProduceConsume.java:148) at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:136) at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:671) at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:589) at java.lang.Thread.run(Thread.java:745) The concept of a "SynchronousAsynchronousResponse" and implementation of in particular SynchronousDispatcher#invoke seem to be totally not what I want: /** * Callback by the initial calling thread. This callback will probably do nothing in an asynchronous environment * but will be used to simulate AsynchronousResponse in vanilla Servlet containers that do not support * asychronous HTTP. * */ request.getAsyncContext().getAsyncResponse().initialRequestThreadFinished(); What am I doing wrong? How do I get truly asynchronous processing? This is with RESTEasy 3.0.18 running on Jetty 9.3.11 Thanks for any advice, Steven_______________________________________________ resteasy-dev mailing list resteasy-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/resteasy-dev_______________________________________________ resteasy-dev mailing list resteasy-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/resteasy-dev