[resteasy-dev] RESTEasy asynchronous processing with @Suspended -- actually synchronous?

Jim Ma ema at redhat.com
Mon Oct 17 10:00:45 EDT 2016


HttpServlet30Dispatcher is also configured as default servlet dispatcher 
in Servlet 3.0 containers via the ServletContainerInitializer if there 
is no resteasy servlet or filter is defined in web.xml.
Filter30Dispatcher and HttpServlet30Dispatcher can all be set to process 
@Suspend.  But as old FilterDispatcher, it candelegate back to the base 
servlet container to resolve URLs if
a JAX-RS resource is not found.

On 10/13/2016 12:24 AM, Rebecca Searls wrote:
> 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 at opentable.com>
>> To: resteasy-dev at 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,
>> Steven
>>
>>> On Oct 7, 2016, at 1:21 PM, Steven Schlansker <sschlansker at 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 at 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 at lists.jboss.org
>> https://lists.jboss.org/mailman/listinfo/resteasy-dev
>>
> _______________________________________________
> resteasy-dev mailing list
> resteasy-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/resteasy-dev


-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/resteasy-dev/attachments/20161017/e68a71c6/attachment.html 


More information about the resteasy-dev mailing list