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.