dev@grizzly.java.net

Re: grizzly 1.9.18b issue with suspend/resume

From: rama <rama.rama_at_tiscali.it>
Date: Wed, 16 Sep 2009 21:47:08 +0200

> Hi Rama,
>
> please write a test for us :)))
>
> Thanks.
>
> WBR,
> Alexey.


Here we go :)

the test is quite bad wrote, i know :) probably i have even entered
some non threadsafe piece
or some excessive locking who know :D

In any case i think that this will give to you an idea of what i do on
my code. And also, i was able
to reproduce this error, using NGNX (or what-the-hell is the name of
this webserver) as a reverseproxy (not provided by me, but
by the society that we use as a reverseproxy ddos protection)

So, a brief explain of that. (the part on parenthesis are the 'real
usage' expalation)

When a request (to a special url that i call /push) the request is
parsed in a different way.
(the session is created from cookie, check if the user is logged,
check if htere are messages for that user, and if not..)
the request will be stopped, and after X second (or when someone add a
messages for that user -not in the test case-) the
request is resumed.

This case is quite simplified, the usage case use and Executor to
resume the request, to avoid blocking. Also the real case, is
threadsafe :) (haven't checked this one sorry)


In any case, i have noticed that sometimes the request isn't resumed
properly, or at least the data isnt' received when i pass through the
revproxy.
I have also ckecked it with a "stupid" request (ie open socket, wrote
GET / HTTP/1.0 and wait for response) and some times i get an error
(but nothing on
grizzly console)

Hope that this help!


---------------
import java.io.IOException;
import java.util.ArrayList;
import java.util.Vector;
import com.sun.grizzly.http.embed.GrizzlyWebServer;
import com.sun.grizzly.tcp.CompletionHandler;
import com.sun.grizzly.tcp.http11.GrizzlyAdapter;
import com.sun.grizzly.tcp.http11.GrizzlyRequest;
import com.sun.grizzly.tcp.http11.GrizzlyResponse;
import com.sun.tools.javac.tree.Tree.Synchronized;

public class Main {

        
        public static void main(String[] args) throws Exception {
                new Main();
        }
        
        Main() {
                final pusher p = new pusher();
                GrizzlyWebServer ws = new GrizzlyWebServer(8080,"",false);
                ws.getSelectorThread().setCompression("on");
                ws.addGrizzlyAdapter(new GrizzlyAdapter() {
                        public void service(final GrizzlyRequest req, final GrizzlyResponse
res) {
                                        if (!res.isSuspended()) {
                                                //request isn't suspended, suspend it, and put it somewhere
                                                //for a later resume :)
                                                res.suspend(Long.MAX_VALUE, this, new
CompletionHandler<GrizzlyAdapter>() {

                                                        public void cancelled(GrizzlyAdapter attachment) {
                                                                        throw new Error("?!?");
                                                        }

                                                        public void resumed(GrizzlyAdapter attachment) {
                                                                  attachment.service(req,res);
                                      try {
                                                                        attachment.afterService(req,res);
                                                                  } catch (Exception e) {
                                                                        e.printStackTrace();
                                                                  }
                                                        }
                                                });
                                                p.add(res);
                                                System.out.println("SUSPEND");
                                                return;
                                                
                                        }
                                        //if i am here, request was suspended, then resumed, and we are
able to write
                                        //something out
                                        System.out.println("OUT");
                                        try {
                                                res.getWriter().print("YEY");
                                        } catch (Exception e){
                                                e.printStackTrace();
                                        }
                        }
                },new String[]{});
                try {
                        ws.start();
                } catch (IOException e) {
                
                        e.printStackTrace();
                }
        }

        
        class pushOBJ {
                GrizzlyResponse res;
                int timeout;
                public pushOBJ(GrizzlyResponse r, int i) {
                        this.timeout = i;
                        this.res = r;
                }
                
        }
        class pusher extends Thread {
                 private Vector<pushOBJ> LIST= new Vector<pushOBJ>();
                 pusher() {
                         start();
                 }
                
                 public void add(GrizzlyResponse r) {
                         synchronized (LIST) {
                                 LIST.add(new pushOBJ(r,10));
                         }
                 }
                 public void run() {
                         while (true) {
                                
                                 synchronized (LIST) {
                                         for (int i = 0;i<LIST.size();i++) {
                                                
                                                 pushOBJ tmp = LIST.get(i);
                                                
                                                 System.out.println("CHECK "+tmp.timeout);
                                                 tmp.timeout--;
                                                 if (tmp.timeout == 0) {
                                                         //ersume request, remove this from list
                                                         LIST.remove(i);
                                                         i--; //dirty :D
                                                         tmp.res.resume();
                                                         System.out.println("RESUME!");
                                                 }
                                                 try {
                                                        LIST.wait(1000);
                                                } catch (InterruptedException e) {
                                                        // TODO Auto-generated catch block
                                                        e.printStackTrace();
                                                }
                                                
                                         }
                                 }
                         }
                 }
        }
}