users@grizzly.java.net

RE: Grizzly Suspend

From: Gay David (Annecy) <"Gay>
Date: Tue, 21 Jun 2011 09:36:09 +0000

Hi Alexey,

I'm trying to reproduce the problem with a simple test case but without success for the moment.
Too bad for me :-(

One question : I'm using the suspend method, by passing a Completion handler.
In this completion handler I do 2 things :

* I generate a default html page if the underlying adapter (could be a simple Adapter, or a GrizzlyAdapter) generate an http error, something like :

private void generateHtmlReplyIfErrorStatus( Request req, Response res )
{
         if (res.getStatus() != OK.getCode()&& !res.isCommitted() ) {
                            byte[] content = getHtmlPageErrorFor( res.getStatus );
                            chunk = new ByteChunk();
                            chunk.setBytes( content, 0, content.length );
                            res.setContentLength( content.length );
                            res.setContentType( "text/html" );
                            res.sendHeaders();
                            res.doWrite( chunk );
}
}

* And I flush the response :

         protected void flushResponse( Request request, Response response ) {
                            try {
                                      GrizzlyRequest grizzlyRequest = (GrizzlyRequest) request.getNote( ADAPTER_NOTES );
                                      GrizzlyResponse grizzlyResponse = (GrizzlyResponse) response.getNote( ADAPTER_NOTES );

                                      if (grizzlyRequest != null && grizzlyResponse != null) {
                                               grizzlyResponse.flushBuffer();
                                      }
                                      else {
                                               response.flush();
                                      }
                            } catch (Exception ex) {
                                      logger.log( Level.WARNING, "Error during request flushing termination", ex );
                            }
                   }
         }

Do you think it's a problem to do that in the completion handler (eventually writing and flushing) ?

Thanks for your help

Regards
David

De : Oleksiy Stashok [mailto:oleksiy.stashok_at_oracle.com]
Envoyé : mercredi 15 juin 2011 19:40
À : users_at_grizzly.java.net
Objet : Re: Grizzly Suspend

Hi David,

can you pls. provide a working sample, which i can run locally to reproduce the issue?

Thanks.

WBR,
Alexey.

On 06/15/2011 06:56 PM, Gay David (Annecy) wrote:
Hi all,

Just an update : I modify my code to execute the code when the RejectedExecutionException in a separate thread.
And after several tests I do not see the Grizzly error anymore.

So, my first conclusion is that it may be related to suspend() and resume() calls in the same Grizzly thread that is the cause of the problem.


Regards
David

De : Gay David (Annecy) [mailto:dgay_at_axway.com]
Envoyé : mercredi 15 juin 2011 17:02
À : users_at_grizzly.java.net<mailto:users_at_grizzly.java.net>
Objet : Grizzly Suspend

Hi all,

I'm using Grizzly 1.9.35 and I have a problem with the suspend/resume feature.
Basically, I delegate to some threads the Grizzly request.
So, in my adapter, in the method service( request, response ) I do :
- response.suspend( ... )
- give the request to my own worker, and when it's finish, call response.resume()

Sometimes, under heavy load, I have a problem, when I ask to suspend the request I have this error :

2011-06-15 16:06:39,340 GMT+0200 - [Grizzly-8090(4)] ERROR (AdapterMapper.service:122) - Error while trying to suspend a request
java.lang.NullPointerException
         at com.sun.grizzly.tcp.SuspendResponseUtils.attach(SuspendResponseUtils.java:61)
         at com.sun.grizzly.tcp.Response.suspend(Response.java:945)
         at com.sun.grizzly.tcp.Response.suspend(Response.java:884)
         at com.axway.drw.core.http.internal.AdapterMapper.service(AdapterMapper.java:118)
         at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:822)
         at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:719)
         at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1013)
         at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225)
         at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
         at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
         at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
         at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
         at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
         at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
         at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
         at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
         at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
         at java.lang.Thread.run(Thread.java:662)

I should do something wrong somewhere.

Can someone suggest me what could be the cause of this error ?
Maybe this error suggest that a miss to resume somewhere ?
Could it be a Grizzly problem ?

This is a simplify code of my adapter :

@Override
public void service( Request req, Response res ) throws Exception {

         try {
                   res.suspend( Long.MAX_VALUE, someDataForTheCompletion, new MyCompletionHandler(req,res) );
         }
         catch ( Exception ex ) {
                   log.log( SEVERE, "Error while trying to suspend a request", ex );
         }

         try {
AsynchronousRequest asyncReq = new AsynchronousRequest( req, res );
                   getMyExecutor().register( asyncReq );
         }
         catch( RejectedExecutionException ex ) {
                   res.setStatus( 509 );
                   res.setMessage( "Too many requests" );
                   res.resume();
                   log.log( INFO, "Asynchronous request cannot be treated by the server: too many requests" );
         }
}

As you see, if my executor is too busy, it set an http error and resume the response. It means that sometimes, the resume is in the Grizzly thread, sometimes not.


Thanks for any help
Regards, David.