保证在GAE中仅将任务添加到推送队列一次

时间:2017-08-21 04:23:00

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

我想确保一项任务 - 尤其是在单个实体上运行的任务 - 最多被添加到推送队列一次,直到之前添加的任务完成为止。然后我应该能够再次为同一个实体添加相同的任务。

一个简单的例子是更新实体A的任务。我希望能够:

  1. 添加任务X以将实体A更新为推送队列。
  2. 当任务X在实体A的队列中时,为实体A添加任务X的所有其他尝试都将失败。
  3. 完成后,我应该再次能够为实体A添加任务X.
  4. 简单的解决方案似乎是使用包含任务X的名称和实体A的唯一ID的任务名称。

    然而,我认为这种方法不满足条件3:任务名称在不可控制的时期内被“逻辑删除”。直到那时才能重复使用。

    来自docs

      

    分配您自己的任务名称的一个优点是命名任务   重复数据删除,这意味着您可以使用任务名称来保证*   任务只添加一次。重复数据删除后持续了9天   任务完成或删除。

    这是否意味着任务名称在9天内无法重复使用?

2 个答案:

答案 0 :(得分:1)

实际上,任务名称在不再排在队列中后9天内无法重复使用。可能是确保以前同名命令的所有痕迹都从整个分布式红外线中刷新的安全原因。

您可以在任务名称中编码当前时间戳,四舍五入到整秒,这会将您的实际写入速率限制为1 / s(这是对同一实体组的最大平均写入速率)。如果您未能将任务排入队列(因为它已经在队列中),您会尝试将其中一个排队等候下一秒(如果您没有其他方法可以触发另一个更新任务)。 但是要将时间戳编码到任务名称的末尾而不是开头,以避免在您引用的同一文档中提到的性能影响。

答案 1 :(得分:1)

我过去曾使用过这个用例,我需要对单个实体进行大量的小更新,但不需要立即反映更新。我通过在拉取队列中批量处理更新解决了这个问题,我每隔X分钟运行一次cron作业就可以执行大量任务并进行批量更新。在我的情况下,cron作业只是将任务排入推送队列。然后,任务从pull队列中消耗并执行事务更新。

参考文档https://cloud.google.com/datastore/docs/articles/fast-and-reliable-ranking-in-datastore/