dev@grizzly.java.net

Re: grizzly 1.9.18b issue with suspend/resume

From: Oleksiy Stashok <Oleksiy.Stashok_at_Sun.COM>
Date: Tue, 29 Sep 2009 14:21:43 +0200

Hi Rama,

sorry, just got some time to take a look at your sample.

IMHO the most suspicious part here is following:

                         public void resumed(GrizzlyAdapter
attachment) {
                             attachment.service(req, res);
                             try {
                                 attachment.afterService(req, res);
                             } catch (Exception e) {
                                 e.printStackTrace();
                             }
                         }

Not sure it's good idea to call service and afterService from your code.
I'd rather suggest something like that:

                         public void resumed(GrizzlyAdapter
attachment) {
                             //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();
                             }
//
// attachment.service(req, res);
// try {
// attachment.afterService(req, res);
// } catch (Exception e) {
// e.printStackTrace();
// }
                         }


Please let me know if your app still doesn't work.

WBR,
Alexey.


On Sep 16, 2009, at 21:47 , rama wrote:

>
>> 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();
> }
>
> }
> }
> }
> }
> }
> }
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe_at_grizzly.dev.java.net
> For additional commands, e-mail: dev-help_at_grizzly.dev.java.net
>