Basic AppEngine Asynchronous Tasks

by

Google’s AppEngine is a very useful platform in the way it allows developers to have an application server up and running within 10 minutes.
It leverages the Google infrastructure, too, offering high speed, high capacity, etc.

Wow (Awesome!)

However (Hmm), AE does not allow for the usual multi-threading mechanisms…

For security reasons, Google sandboxes your applications.
For resource management reasons, Google also tries to keep a hold of processes within your app. The Java Thread class is only partially supported; you can’t start a Thread, but you can put a Thread to sleep: Thread.sleep(1000);

How can I multithread with AppEngine?

AppEngine does provides a service to run tasks asynchronously.
We get a hold of a Queue onto which we can submit serialized Tasks. You can actually keep track of your queues on the AppEngine dashboard (See Left Menu -> Task Queues).

Queue myQueue = QueueFactory.getDefaultQueue();
myQueue.add(...);

To create your own task, implement the DeferredTask interface.

public class MyTask implements DeferredTask {
    private static final Logger log = Logger.getLogger(My.class.getName());
    public MyTask() {}

    @Override
    public void run() {
        // Code for all your hearts content
        log.info("Giants World-series Champions!");
    }
}

And then:

MyTask myTask = new MyTask();
myQueue.add(TaskOptions.Builder.withPayload(myTask));

That’s it.

You might want to give a name to your task; that will allow you to clean up later on if you need to.

MyTask myTask = new MyTask();
String myVeryOwnTask = "MyVeryOwnTask"
queue.add(TaskOptions.Builder.withPayload(myTask).taskName(myVeryOwnTask);
...
queue.deleteTask(myVeryOwnTask);

Note: The task is serialized using the Serializable interface; make sure your members implement it as well.

This is just the beginning. There are multiple options that you can set when adding a task to a queue, like what happens when a task fails: should it retry? You can find more details about threading with AppEngine on their Google Docs.

2 Comments

  1. Good question!

    You can set the countdown before your task is run using either:

    TaskOptions.Builder.withCountdownMillis(long countdownMillis) 
    

    or

    TaskOptions.countdownMillis(long countdownMillis)
    

    Specifying the delay in milliseconds.

    In the example above, for a 20 seconds delay you would write:

    queue.add(
       TaskOptions.Builder
          .withPayload(myTask)
             .taskName(myVeryOwnTask)
             .countdownMillis(20000L);
    

    See TaskOptions and TaskOptions.Builder for more options.

Leave a Reply

Your email address will not be published. Required fields are marked *