[resteasy-dev] RESTEasy asynchronous processing with @Suspended -- actually synchronous?
Rebecca Searls
rsearls at redhat.com
Wed Oct 12 12:24:25 EDT 2016
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
>
More information about the resteasy-dev
mailing list