IAmYourFaja
IAmYourFaja

Reputation: 56904

Synchronization required for multithreaded GAE apps?

Google App Engine allows you to create threads if you use their ThreadManager.currentRequestThreadFactory() in conjunction with an ExecutorService. So, in order to allow the same frontend instance to handle multiple servlet requests at the same time, I am planning on writing code that looks like the following:

public class MyServlet implements HttpServlet {
    private RequestDispatcher dispatcher;

    // Getter and setter for 'dispatcher'.

    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) {
        MyResponse resp = dispatcher.dispatch(request);

        PrintWriter writer = response.getWriter();

        // Use the 'resp' and 'writer' objects to produce the resultant HTML
        // to send back to the client. Omitted for brevity.
    }
}

public class RequestDispatcher {
    private ThreadFactory threadFactory =
        ThreadManager.currentRequestThreadFactory();

    private Executor executor;

    // Getters and setters for both properties.

    public MyResponse dispatch(HttpServletRequest request) {
        if(executor == null)
            executor = Executors.newCachedThreadPool(threadFactory);

        // MyTask implements Callable<MyResponse>.
        MyTask task = TaskFactory.newTask(request);

        MyResponse myResponse = executor.submit(task);
    }
}

So now I believe we have a setup where each frontend will have a servlet that can accept up to 10 (I believe that's the max for what GAE allows) requests at the same time, and process all of them concurrently without blocking. So first off, if I've mistaken the use of ThreadManager and am not using it correctly, or if my setup for this type of concurrent behavior is incorrect, please begin by correcting me!

Assuming I'm more or less on track, I have some concurrency-related concerns with how Google App Engine threads utilize the object tree underneath the MyTask object.

The MyTask callable is responsible for actually processing the HTTP request. In EJB land, this would be the "business logic" code that does stuff like: (1) placing messages on a queue, (2) hitting the Google Datastore for data, (3) saving stuff to a cache, etc. The point is, it spawns a big "object tree" (lots of subsequent child objects) when its call() method is executed by the Executor.

Do I have to make each and every object that gets created from inside MyTask#call thread-safe? Why or why not? Thanks in advance!

Upvotes: 0

Views: 201

Answers (1)

JB Nizet
JB Nizet

Reputation: 691685

You don't need all this to enable an instance to process multiple requests concurrently. GAE allows you to spawn threads if you need to perform multiple tasks in parallel when handling a single given request.

It could be useful, for example, if you need to contact several external URLs in parallel to get information needed to respond to a given request. This would be more efficient tha contacting all the URLs in sequence.

Upvotes: 2

Related Questions