【问题标题】:Use POJO in app engine Task Queue在应用引擎任务队列中使用 POJO
【发布时间】:2015-04-04 21:16:40
【问题描述】:

是否可以在 App-Engine 任务队列中使用 POJO?或者值必须始终是字符串?

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

如果我的 POJO 很复杂,以至于 POJO 中的字段之一是 ArrayList,该怎么办?

【问题讨论】:

    标签: java google-app-engine task-queue


    【解决方案1】:

    TaskOptions'param 方法有两个重载:一个采用String,另一个采用byte[]。 POJO 实现了java.io.Serializable,因此您可以将一个序列化为byte[],如Java Serializable Object to Byte Array 所示(并在接收时反序列化byte[])。

    每个 https://cloud.google.com/appengine/docs/python/taskqueue/overview-push#Python_Quotas_and_limits_for_push_queues 的最大任务大小为 100 KB(因此 byte[] 有效负载的最大大小必须比这小一些)。如果这对您来说是个问题,您可以考虑将 POJO 作为实体存储在数据存储中,然后发送相应的密钥...

    【讨论】:

      【解决方案2】:

      您可以使用 deferred task,它是像常规任务一样在队列上启动的对象。基本上,它是通过 TaskQueue 选项启动的不同线程,您可以传递 可序列化对象 而不是普通的 http 参数。

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

      虽然 DeferredTask API 是一种处理序列化的便捷方式

      你需要创建一个扩展DeferredTask的类(它有一个接收你的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
          }
      }
      

      然后启动任务

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

      这样做的好处是,如果负载大于 100kb,POJO 会自动保存在数据存储中(最多 1 MB,作为数据存储条目限制),然后在您的任务开始时检索。

      【讨论】:

      • 谢谢!这是我正在寻找的,但在docs 中缺少。从文档中,同样重要的是要注意:“...仔细控制是必要的,因为未处理的对象仍保留在任务队列中,即使在更新应用程序代码之后也是如此。基于过时应用程序代码的任务在任务完成时将无法正确反序列化使用应用程序的新版本进行解码。”
      猜你喜欢
      • 2012-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多