Correct usage of suspend/resume with jersey?

classic Classic list List threaded Threaded
17 messages Options
Reply | Threaded
Open this post in threaded view
|

Correct usage of suspend/resume with jersey?

tmkha
I have some web-services based on jersey which adapt requests from HTTP to Thrift services.  The thrift responses might take a little time.  For scalability purpose, I would like to port these web-services to an async framework.

I was exploring servlet 3.0 and ran across Atmosphere-jersey suspend/resume mechanism, which seems be a natural path to for my async jersey based web-services.  I have created the following prototype and someone can help me with the following questions:
1. Is there any issue with this implementation?
2. I saw a JerseyBroadcaster.  Should I be using it?  If so, why it should be used and how it should be used?
3. I might also plan to use the same implementation for a comet use-case by caching the AtmosphereResource and resuming the session when there is an event from RabbitMQ.  Do you see any problem with that?
4. How do I make this producing JSON?  I changed to @Produce("application/json") and included jersey-json-1.6.jar, but always got this error:
Caused by: com.sun.jersey.api.MessageException: A message body writer for Java class java.util.ArrayList, and Java type java.util.List<java.lang.String>, and MIME media type application/json was not found

Here is the resource implementation:

@Singleton
@Path("/helloworld")
public class SampleAsyncController  {
    private static final Logger logger = LoggerFactory.getLogger(SampleAsyncController.class);
    private Executor executor =
        new ThreadPoolExecutor(10, 10, 50000L,
            TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<Runnable>(100));
    @GET
    @Produces("text/html")
    @Suspend( resumeOnBroadcast = true, period = 25, scope = Suspend.SCOPE.REQUEST,
            timeUnit = java.util.concurrent.TimeUnit.SECONDS, outputComments = false)
    public String asyncRequest(final @Context HttpServletRequest hsreq) {
        @SuppressWarnings("unchecked")
        final AtmosphereResource<HttpServletRequest, HttpServletResponse> resource =
            (AtmosphereResource<HttpServletRequest, HttpServletResponse>)
            hsreq.getAttribute(AtmosphereServlet.ATMOSPHERE_RESOURCE);
        if (resource == null) {
            logger.error("there is not atmosphere resource in request");
            return "there is not atmosphere resource in request";
        }
        logger.info("SampleAsyncController gets request w/ path: {}",
                resource.getRequest().getPathInfo());
        Runnable job = new Runnable() {
            public void run() {
                try {
                    logger.info("artificially suspending request for 5secs just to simulate thrift call");
                    Thread.sleep(5000);
                } catch (InterruptedException e1) {
                }
                logger.info("resuming request");
                HttpServletRequest _request = resource.getRequest();
                String name = _request.getParameter("who");
                StringBuffer out = new StringBuffer();
                out.append("<html>");
                out.append("<head>");
                out.append("<title>HelloWorld</title>");
                out.append("</head>");
                out.append("<body>");
                if (name == null) {
                    out.append("*** atmosphere-async-jersey: who are you? ***");
                } else {
                    out.append("*** atmosphere-async-jersey: hello " + name + "! ***");
                }
                out.append("</body>");
                out.append("</html>");

                Broadcaster bc = resource.getBroadcaster();
                logger.info("Broadcaster: {}", bc.getClass().getName());
                bc.broadcast(out.toString(), resource);
            }

        };
        executor.execute(job);
        logger.info("SampleAsyncController done");

        return "";
    }

}

Thanks,

Triet
Reply | Threaded
Open this post in threaded view
|

Re: Correct usage of suspend/resume with jersey?

tmkha
I deployed this on Tomcat 7, applied a little load on it, and periodically getting the following exception. Just wonder if anyone can help me identify the cause:

[http-bio-8080-exec-1] ERROR org.atmosphere.jersey.AtmosphereFilter  - failed to instantiate broadcaster with factory: org.atmosphere.cpr.DefaultBroadcasterFactory@27905a42
java.lang.IllegalStateException: Broadcaster ID already assigned to SCOPE.REQUEST. Cannot change the id
   at org.atmosphere.cpr.DefaultBroadcaster.setID(DefaultBroadcaster.java:212)
   at org.atmosphere.jersey.AtmosphereFilter$Filter.suspend(AtmosphereFilter.java:470)
   at org.atmosphere.jersey.AtmosphereFilter$Filter.filter(AtmosphereFilter.java:244)
   at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1289)
   at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1223)
   at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1213)
   at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:414)
   at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537)
   at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:699)
   at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
   at org.atmosphere.util.AtmosphereFilterChain.doFilter(AtmosphereFilterChain.java:155)
   at org.atmosphere.util.AtmosphereFilterChain.invokeFilterChain(AtmosphereFilterChain.java:116)
   at org.atmosphere.handler.ReflectorServletProcessor$FilterChainServletWrapper.service(ReflectorServletProcessor.java:294)
   at org.atmosphere.handler.ReflectorServletProcessor.onRequest(ReflectorServletProcessor.java:152)
   at org.atmosphere.cpr.AsynchronousProcessor.action(AsynchronousProcessor.java:191)
   at org.atmosphere.cpr.AsynchronousProcessor.suspended(AsynchronousProcessor.java:142)
   at org.atmosphere.container.Servlet30Support.service(Servlet30Support.java:87)
   at org.atmosphere.cpr.AtmosphereServlet.doCometSupport(AtmosphereServlet.java:1156)
   at org.atmosphere.cpr.AtmosphereServlet.doPost(AtmosphereServlet.java:1138)
   at org.atmosphere.cpr.AtmosphereServlet.doGet(AtmosphereServlet.java:1124)
   at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
   at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
   at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
   at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
   at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
   at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
   at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
   at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:851)
   at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
   at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405)
   at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:278)
   at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515)
   at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:300)
   at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
   at java.lang.Thread.run(Thread.java:680)

Thanks,

Triet
Reply | Threaded
Open this post in threaded view
|

Re: Correct usage of suspend/resume with jersey?

tmkha
Also, it eventually got into out-of-memory with 'unable to create native thread'.  Does it look obvious to anyone why it would have problem creating native thread with the implementation I posted earlier?

Thanks,

Triet
Reply | Threaded
Open this post in threaded view
|

Re: Correct usage of suspend/resume with jersey?

tmkha
Here is the trace stack when the "OutOfMemoryException - unable to create native thread" occurred:
java.lang.OutOfMemoryError: unable to create new native thread
        at java.lang.Thread.start0(Native Method)
        at java.lang.Thread.start(Thread.java:658)
        at java.util.concurrent.ThreadPoolExecutor.addIfUnderMaximumPoolSize(ThreadPoolExecutor.java:727)
        at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:657)
        at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:78)
        at org.atmosphere.cpr.DefaultBroadcaster$3.run(DefaultBroadcaster.java:518)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
        at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
        at java.util.concurrent.FutureTask.run(FutureTask.java:138)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)

jstack showed that I have about 2000 threads with the names of "Atmosphere-AsyncWrite-x" and "Atmosphere-BroadcasterConfig-x".

Look like my the Broadcaster related threads were not released properly, so look like I wasn't using it properly.

Can anyone please help?

Thanks,

Triet
Reply | Threaded
Open this post in threaded view
|

Re: Correct usage of suspend/resume with jersey?

Tính Trương Xuân
Hi Triet,

Basically, you can configure Atmosphere to mange the life cycle of the broadcasters.

Regards,
Tinh

On Thu, Jul 28, 2011 at 4:27 PM, tmkha <[hidden email]> wrote:
Here is the trace stack when the "OutOfMemoryException - unable to create
native thread" occurred:
java.lang.OutOfMemoryError: unable to create new native thread
       at java.lang.Thread.start0(Native Method)
       at java.lang.Thread.start(Thread.java:658)
       at
java.util.concurrent.ThreadPoolExecutor.addIfUnderMaximumPoolSize(ThreadPoolExecutor.java:727)
       at
java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:657)
       at
java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:78)
       at org.atmosphere.cpr.DefaultBroadcaster$3.run(DefaultBroadcaster.java:518)
       at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
       at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
       at java.util.concurrent.FutureTask.run(FutureTask.java:138)
       at
java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)

jstack showed that I have about 2000 threads with the names of
"Atmosphere-AsyncWrite-x" and "Atmosphere-BroadcasterConfig-x".

Look like my the Broadcaster related threads were not released properly, so
look like I wasn't using it properly.

Can anyone please help?

Thanks,

Triet

--
View this message in context: http://atmosphere-users-mailling-list.2493822.n2.nabble.com/Correct-usage-of-suspend-resume-with-jersey-tp6625131p6629231.html
Sent from the Atmosphere users mailling list mailing list archive at Nabble.com.

Reply | Threaded
Open this post in threaded view
|

Re: Correct usage of suspend/resume with jersey?

tmkha
Tinh.  Thanks for the reply.

I haven't been able to find out how/where to configure the BroadcasterLifecylePolicy.  Is it in the atmosphere.xml?  Can you please give me some examples/pointers?

For my use case, I have:
- a request that comes in
- an async thread pool is used to prepare the response
- the request is suspended
- response is ready, the async thread pool resume the request and a new broadcaster is created (which has its own executor) to send the response
- (if i configure it correctly, then the broadcaster is destroyed after the response is sent)

It seems to be expensive to create a new broadcaster to send response for every request.  Is it possible to create a static broadcaster and share that for sending all response? (please note that i am using this more for async request processing; not so much about sub/pub).

Also, can i send response back directly to the HttpServletResponse without using Broadcaster?  I initially tried to get the HttpServletResponse from the AtmosphereResource but got a null pointer.

Thanks,

Triet
Reply | Threaded
Open this post in threaded view
|

Re: Correct usage of suspend/resume with jersey?

P Osborne

Hi Triet,

I have looked at this code before and its why I don't use more than one broadcaster with Atmosphere, the code just isn't thread safe.  It is possible to broadcast only to a single resource, instead of creating a separate broadcaster.

Cheers,
Patrick

On Thu, Jul 28, 2011 at 11:44 AM, tmkha <[hidden email]> wrote:
Tinh.  Thanks for the reply.

I haven't been able to find out how/where to configure the
BroadcasterLifecylePolicy.  Is it in the atmosphere.xml?  Can you please
give me some examples/pointers?

For my use case, I have:
- a request that comes in
- an async thread pool is used to prepare the response
- the request is suspended
- response is ready, the async thread pool resume the request and a new
broadcaster is created (which has its own executor) to send the response
- (if i configure it correctly, then the broadcaster is destroyed after the
response is sent)

It seems to be expensive to create a new broadcaster to send response for
every request.  Is it possible to create a static broadcaster and share that
for sending all response? (please note that i am using this more for async
request processing; not so much about sub/pub).

Also, can i send response back directly to the HttpServletResponse without
using Broadcaster?  I initially tried to get the HttpServletResponse from
the AtmosphereResource but got a null pointer.

Thanks,

Triet

--
View this message in context: http://atmosphere-users-mailling-list.2493822.n2.nabble.com/Correct-usage-of-suspend-resume-with-jersey-tp6625131p6630684.html
Sent from the Atmosphere users mailling list mailing list archive at Nabble.com.

Reply | Threaded
Open this post in threaded view
|

Re: Correct usage of suspend/resume with jersey?

tmkha
In reply to this post by tmkha
ok. I found the answer for the BroadcasterLifeCyclePolicy configuration.  it can be done as part of web.xml init-param:
    org.atmosphere.cpr.broadcasterLifeCyclePolicy
    {NEVER, IDLE, IDLE_DESTROY, EMPTY, EMPTY_DESTROY}

If anyone has any info on the other questions I posted, it would be greatly appreciate.

Triet
Reply | Threaded
Open this post in threaded view
|

Re: Correct usage of suspend/resume with jersey?

Jeanfrancois Arcand-4
In reply to this post by P Osborne
Salut,

On 11-07-28 3:26 PM, P Osborne wrote:
>
> Hi Triet,
>
> I have looked at this code before and its why I don't use more than one
> broadcaster with Atmosphere, the code just isn't thread safe.

Can you point me to the issue? I think it needs to be fixed ASAP.

Thanks!

-- Jeanfrancois


  It is

> possible to broadcast only to a single resource, instead of creating a
> separate broadcaster.
>
> Cheers,
> Patrick
>
> On Thu, Jul 28, 2011 at 11:44 AM, tmkha <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>     Tinh.  Thanks for the reply.
>
>     I haven't been able to find out how/where to configure the
>     BroadcasterLifecylePolicy.  Is it in the atmosphere.xml?  Can you please
>     give me some examples/pointers?
>
>     For my use case, I have:
>     - a request that comes in
>     - an async thread pool is used to prepare the response
>     - the request is suspended
>     - response is ready, the async thread pool resume the request and a new
>     broadcaster is created (which has its own executor) to send the response
>     - (if i configure it correctly, then the broadcaster is destroyed
>     after the
>     response is sent)
>
>     It seems to be expensive to create a new broadcaster to send
>     response for
>     every request.  Is it possible to create a static broadcaster and
>     share that
>     for sending all response? (please note that i am using this more for
>     async
>     request processing; not so much about sub/pub).
>
>     Also, can i send response back directly to the HttpServletResponse
>     without
>     using Broadcaster?  I initially tried to get the HttpServletResponse
>     from
>     the AtmosphereResource but got a null pointer.
>
>     Thanks,
>
>     Triet
>
>     --
>     View this message in context:
>     http://atmosphere-users-mailling-list.2493822.n2.nabble.com/Correct-usage-of-suspend-resume-with-jersey-tp6625131p6630684.html
>     Sent from the Atmosphere users mailling list mailing list archive at
>     Nabble.com.
>
>
Reply | Threaded
Open this post in threaded view
|

Re: Correct usage of suspend/resume with jersey?

tmkha
In reply to this post by P Osborne
>Hi Triet,
>
>I have looked at this code before and its why I don't use more than one broadcaster with Atmosphere, the >code just isn't thread safe.  It is possible to broadcast only to a single resource, instead of creating a >separate broadcaster.
>
>Cheers,
>Patrick
Patrick, can you describe how this can be done?  AtmospherResource is so tightly integrated with Broadcaster/BroadcasterFactory, and I couldn't really instantiate my own Broadcaster and make the framework to ignore the auto generated Broadcaster.  

The Broadcaster mechanism is great for the Pub/Sub use-case, but seems to be a bit overkilled for a simple suspend/resume use case.  

It would be great if Atmosphere would support a mechanism similar to Servlet 3.0 where we can just call HttpServletRequest.startAsync() to get an AsyncContext and later on resume the processing directly with all the request/response contexts from AsyncContext.

Thanks,

Triet
Reply | Threaded
Open this post in threaded view
|

Re: Correct usage of suspend/resume with jersey?

Jeanfrancois Arcand-4
In reply to this post by tmkha
Salut,

can you privately share a test case. I'm in and out this summer (more
out :-)) so it is hard for me to follow. Send it to [hidden email]
and I will take a look.

Also please file issue using JIRA so I can stay aware of what's happening.

Thanks!

-- Jeanfrancois

On 11-07-27 6:09 PM, tmkha wrote:

> I deployed this on Tomcat 7, applied a little load on it, and periodically
> getting the following exception. Just wonder if anyone can help me identify
> the cause:
>
> [http-bio-8080-exec-1] ERROR org.atmosphere.jersey.AtmosphereFilter  -
> failed to instantiate broadcaster with factory:
> org.atmosphere.cpr.DefaultBroadcasterFactory@27905a42
> java.lang.IllegalStateException: Broadcaster ID already assigned to
> SCOPE.REQUEST. Cannot change the id
>     at
> org.atmosphere.cpr.DefaultBroadcaster.setID(DefaultBroadcaster.java:212)
>     at
> org.atmosphere.jersey.AtmosphereFilter$Filter.suspend(AtmosphereFilter.java:470)
>     at
> org.atmosphere.jersey.AtmosphereFilter$Filter.filter(AtmosphereFilter.java:244)
>     at
> com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1289)
>     at
> com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1223)
>     at
> com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1213)
>     at
> com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:414)
>     at
> com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537)
>     at
> com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:699)
>     at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
>     at
> org.atmosphere.util.AtmosphereFilterChain.doFilter(AtmosphereFilterChain.java:155)
>     at
> org.atmosphere.util.AtmosphereFilterChain.invokeFilterChain(AtmosphereFilterChain.java:116)
>     at
> org.atmosphere.handler.ReflectorServletProcessor$FilterChainServletWrapper.service(ReflectorServletProcessor.java:294)
>     at
> org.atmosphere.handler.ReflectorServletProcessor.onRequest(ReflectorServletProcessor.java:152)
>     at
> org.atmosphere.cpr.AsynchronousProcessor.action(AsynchronousProcessor.java:191)
>     at
> org.atmosphere.cpr.AsynchronousProcessor.suspended(AsynchronousProcessor.java:142)
>     at
> org.atmosphere.container.Servlet30Support.service(Servlet30Support.java:87)
>     at
> org.atmosphere.cpr.AtmosphereServlet.doCometSupport(AtmosphereServlet.java:1156)
>     at
> org.atmosphere.cpr.AtmosphereServlet.doPost(AtmosphereServlet.java:1138)
>     at
> org.atmosphere.cpr.AtmosphereServlet.doGet(AtmosphereServlet.java:1124)
>     at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
>     at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
>     at
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
>     at
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
>     at
> org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
>     at
> org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
>     at
> org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
>     at
> org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
>     at
> org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
>     at
> org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:851)
>     at
> org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
>     at
> org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405)
>     at
> org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:278)
>     at
> org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515)
>     at
> org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:300)
>     at
> java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
>     at
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
>     at java.lang.Thread.run(Thread.java:680)
>
> Thanks,
>
> Triet
>
> --
> View this message in context: http://atmosphere-users-mailling-list.2493822.n2.nabble.com/Correct-usage-of-suspend-resume-with-jersey-tp6625131p6627943.html
> Sent from the Atmosphere users mailling list mailing list archive at Nabble.com.
>
Reply | Threaded
Open this post in threaded view
|

Re: Correct usage of suspend/resume with jersey?

Jeanfrancois Arcand-4
In reply to this post by tmkha
Salut,

On 11-07-29 1:07 AM, tmkha wrote:

>> Hi Triet,
>>
>> I have looked at this code before and its why I don't use more than one
> broadcaster with Atmosphere, the>code just isn't thread safe.  It is
> possible to broadcast only to a single resource, instead of creating a
>> separate broadcaster.
>>
>> Cheers,
>> Patrick
> Patrick, can you describe how this can be done?  AtmospherResource is so
> tightly integrated with Broadcaster/BroadcasterFactory, and I couldn't
> really instantiate my own Broadcaster and make the framework to ignore the
> auto generated Broadcaster.
>
> The Broadcaster mechanism is great for the Pub/Sub use-case, but seems to be
> a bit overkilled for a simple suspend/resume use case.
>
> It would be great if Atmosphere would support a mechanism similar to Servlet
> 3.0 where we can just call HttpServletRequest.startAsync() to get an
> AsyncContext and later on resume the processing directly with all the
> request/response contexts from AsyncContext.

You can already do that using Jersey by injecting the AtmosphereResource as:

@Context AtmosphereResource atmosphereResource;

and then just grab the HttpServletResponse from that object and do the
same thing as AsyncContext

A+

-- Jeanfrancois



>
> Thanks,
>
> Triet
>
> --
> View this message in context: http://atmosphere-users-mailling-list.2493822.n2.nabble.com/Correct-usage-of-suspend-resume-with-jersey-tp6625131p6632390.html
> Sent from the Atmosphere users mailling list mailing list archive at Nabble.com.
>
Reply | Threaded
Open this post in threaded view
|

Re: Correct usage of suspend/resume with jersey?

tmkha
>You can already do that using Jersey by injecting the AtmosphereResource as:
>
>@Context AtmosphereResource atmosphereResource;
>
>and then just grab the HttpServletResponse from that object and do the
>same thing as AsyncContext
Yes. I have injected AtmosphereResource as follows:

    @GET
    @Produces("text/html")
    @Suspend( resumeOnBroadcast = true, period = 25, scope = Suspend.SCOPE.REQUEST,
            timeUnit = java.util.concurrent.TimeUnit.SECONDS, outputComments = false)
    public String asyncRequest(final @Context AtmosphereResource<HttpServletRequest, HttpServletResponse> resource) { ...}

And I found that I can even write directly to the PrintWriter from the HttpServetResponse acquired from the resource in my async Runabble/Thread with out calling Broadcaster.  (Not sure if this is recommended or caused any problem in the framework though.  Haven't spent anytime to trace Atmosphere code in this path.)

However, the problem is that Atmosphere is still automatically managing the Broadcaster behind the scene. Regardless of whether I am writing directly to HttpServerResponse or through the Broadcaster, I am still getting the following exception, even after I moved to 0.8-SNAPSHOT with Jerysey 1.8:

[http-bio-8080-exec-12] ERROR org.atmosphere.jersey.AtmosphereFilter  - failed to instantiate broadcaster with factory: org.atmosphere.cpr.DefaultBroadcasterFactory@78f7821d
java.lang.IllegalStateException: Broadcaster ID already assigned to SCOPE.REQUEST. Cannot change the id
        at org.atmosphere.cpr.DefaultBroadcaster.setID(DefaultBroadcaster.java:212)
        at org.atmosphere.jersey.AtmosphereFilter$Filter.suspend(AtmosphereFilter.java:470)
        at org.atmosphere.jersey.AtmosphereFilter$Filter.filter(AtmosphereFilter.java:244)

Any idea/suggestion on how to resolve this?

Thanks,

Triet

Reply | Threaded
Open this post in threaded view
|

Re: Correct usage of suspend/resume with jersey?

tmkha
This post has NOT been accepted by the mailing list yet.
In reply to this post by Jeanfrancois Arcand-4
>Salut,
>
>can you privately share a test case. I'm in and out this summer (more
>out :-)) so it is hard for me to follow. Send it to [hidden email]
>and I will take a look.
Hi Jeanfrancois,

Sorry, I missed this message from you for some reason. I have sent the test to your email address at apache.org.  I don't know how to attach the maven project following the [hidden email] link you provided.

I ran the test with jMeter
URL: /atmosphere-async-jersey-test/cowsservices/helloworld?delay=200&who=kha
Number of Thread: 50
Ramp-up Period: 1
Loop Count: 10 to 20

And I can consistently reproduce the problem.  Occasionally, if running with higher number of threads, I also saw some NPE and other exceptions.

I also modified the atmosphere-jersey and atmosphere-cpr source code (0.8-SNAPSHOT) to inject some debug logs (mainly in AtmosphereFilter, DefaultBroadcaster, DefaultBroadcasterFactory where Broadcasters are add/remove and ID are changed/added to factory) and noticed that when the error occurred, there were multiple threads working on the same Broadcaster ID at the same time.

Will create a Jira ticket next.

Thanks,

- Triet
Reply | Threaded
Open this post in threaded view
|

Re: Correct usage of suspend/resume with jersey?

tmkha
Per your request, jira ticket created: http://java.net/jira/browse/ATMOSPHERE-152

Thanks,

Triet
Reply | Threaded
Open this post in threaded view
|

Re: Correct usage of suspend/resume with jersey?

tmkha
Jeanfrancois,

My group needs to make a decision on whether we should move forward with Atmosphere or just use Servlet 3.0 for now until Atmosphere is stable for our use-case.  So I am looking to see if there is a temporary work-around for the issues I noticed in the Broadcaster management.

For now, I don't really the 'broadcasting' functionality.  In my use case, every response send to only the original request, so the AtmosphereResource have captured all the resources I need.  So is there an easy way to disable or override the broadcaster management so my service can just write directly back to the HttpServletResponse and call AtmosphereResource.resume?

Thanks,

Triet
Reply | Threaded
Open this post in threaded view
|

Re: Correct usage of suspend/resume with jersey?

java.net
In reply to this post by tmkha
You should not be getting this exception, so  hopefully Jean Francois
will have some time to have a look at it.

Pierre


On 29-7-2011 17:43, tmkha wrote:
> oadcaster w