1

Is it possible to use POJOs in App-Engine Task Queues? Or must the values always be String?

Queue queue = QueueFactory.getQueue("my_queue");
queue.add(withUrl("/my_worker").param("my_key", obj));

What if my POJO is complex, such that one of the fields in the POJO is an ArrayList?

Katedral Pillon
  • 14,534
  • 25
  • 99
  • 199

2 Answers2

3

TaskOptions' param method has two overloads: one takes a String, the other one takes a byte[]. POJOs implement java.io.Serializable, so you can serialize one to a byte[] as shown e.g at Java Serializable Object to Byte Array (and upon reception deserialize the byte[] back).

The maximum task size, per https://cloud.google.com/appengine/docs/python/taskqueue/overview-push#Python_Quotas_and_limits_for_push_queues , is 100 KB (so the max size of the byte[] payload will have to be somewhat less than that). If that's a problem for you, you could consider stashing the POJO as an entity in the datastore and just sending the corresponding key...

Community
  • 1
  • 1
Alex Martelli
  • 854,459
  • 170
  • 1,222
  • 1,395
3

You can use a deferred task which is an object launched on a queue like a regular task. Basically, it is a different Thread which is launched through the TaskQueue options and you can pass a serializable object instead of plain http parameters.

https://cloud.google.com/appengine/docs/java/taskqueue/overview-push#Java_Deferred_tasks

While the DeferredTask API is a convenient way to handle serialization

You need to create a class which extends DeferredTask (which has a constructor receiving your POJO).

public class MyDeferredTask implements DeferredTask {

    private MyPojo pojo;

    public MyDeferredTask(MyPojo pojo) {
        this.pojo = pojo;
    }

    @Override
    public void run() {
        // TODO Do stuff with pojo
    }
}

and then launch the task

MyDeferredTask task = new MyDeferredTask(pojo);
TaskOptions taskOptions = TaskOptions.Builder.withPayload(task);
TaskManager.getQueue("my-queue").add(taskOptions);

The good thing about this is that the if the payload is greater than 100kb, the POJO is automatically persisted on the datastore (up to 1 MB, as datastore entry limit) and then retrieved when your task starts.

Deviling Master
  • 3,033
  • 5
  • 34
  • 59
  • Thank you! This is what I'm looking for, but missing in the [docs](https://cloud.google.com/appengine/docs/java/taskqueue/overview-push#Java_Deferred_tasks). From the docs, it is also important to note: "...Careful control is necessary because unprocessed objects remain in the task queue, even after the application code is updated. Tasks based on outdated application code will not deserialize properly when the task is decoded with new revisions of the application." – ruhong Feb 14 '16 at 07:37