Hi everyone,

I'm seeing a strange concurrent-requests problem with a very simple
test and am not sure whether it's a bug, a feature, or whether I am
doing something wrong:

Using App-Engine 1.6.1, I wrote the following test-app (modulo the
usual imports and xml files):

--8<--------------

public class Wait extends HttpServlet {
        public static final Semaphore SEMAPHORE = initSemaphore();

        private static Semaphore initSemaphore() {
                Semaphore result = new Semaphore(1, true);
                result.acquireUninterruptibly();
                return result;
        }

        public void doGet(HttpServletRequest req, HttpServletResponse resp) {
                SEMAPHORE.acquireUninterruptibly();
                SEMAPHORE.release();
                resp.getWriter().println("Got event");
        }
}

--8<--------------

public class Release extends HttpServlet {
        public void doGet(HttpServletRequest req, HttpServletResponse resp) {
                Wait.SEMAPHORE.release();
                Wait.SEMAPHORE.acquireUninterruptibly();
                resp.getWriter().println("Sent event");
        }
}

--8<--------------

Now, what I was hoping to see is that I can send several GET requests
to the Wait servlet and have them all "lock up" until I send a GET
request to Release. What instead I see is that a request to Release
releases the Wait requests only ONE at a time. With a little bit of
System.out.println magic, I was able to determine that the reason for
this is that any further requests to Wait don't actually make it into
the doGet-method before the first one is fully handled. In fact,
adding a second copy of the Wait class as follows:

--8<--------------

public class Wait2 extends HttpServlet {
        public void doGet(HttpServletRequest req, HttpServletResponse resp) {
                Wait.SEMAPHORE.acquireUninterruptibly();
                Wait.SEMAPHORE.release();
                resp.getWriter().println("Got event");
        }
}

--8<--------------

allows me to "lock up" one request to Wait and a second one to Wait2
and release them both with a single request to Release.

Deploying the app, I also see that AppEngine launches a second
instance after I have 2 requests pending (which of course renders
Release ineffective, if it happens in a different instance from the
one holding the Wait).

This behavior seems independent of whether I have <threadsafe>true</
threadsafe> in my application-web.xml file or not.

What's strange to me is the inconsistency:
 - On the one hand it clearly allows multi-threaded request handling
inside one instance as I can release a GET request to Wait with a
seperate, simultaneous GET request to Release.
 - On the other hand, it seems to disallow multi-threading within the
same HttpServlet object.
 - Neither one seems to be influenced by <threadsafe>true</
threadsafe>.

A couple of side notes:
- As far as I can tell, the dev-server and the production server
behave identically here.
- I know that I should probably be using Channels instead to achieve
this, but they have two problems for me, namely the lack of fan-out
and the page sending requests to talkgadget.google.com (which might
make users a bit skeptical if you're trying to build a security-
focused service). Also, I'd like to understand this exact issue
independent of potential other approaches as it has a direct impact on
billing (multiple requests to the same Servlet triggering more
instances).


I am hoping that one of you might have a thought on how I could crack
this.


Thanks,

  Markus

-- 
You received this message because you are subscribed to the Google Groups 
"Google App Engine" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/google-appengine?hl=en.

Reply via email to