以下简单模式是否足以确保即使在应用程序更新或严重“不稳定”的谷歌失败后,任务序列也不会停止。
def do_work():
... ....
deferred.defer(do_work, _countdown=..in 7 days..)
我可以安排这样一个自我调度的工作人员,永远不要回头吗?
答案 0 :(得分:2)
两个答案:
是的,任务最终会执行,并且还会在任务执行出错时重试执行。定义任务时会设置重试选项。
不,任务队列不是调度程序,因此您无法安排任务在特定时间运行。放入任务队列的任务将以FIFO方式立即提供。
正如@Jesse所指出的,对于安排工作,你应该研究GAE cron。
答案 1 :(得分:1)
如果任务排队成功,它最终会执行。 (并且App Engine会一直尝试。)
您使用cron jobs可能会更好地实现您显示的模式,它会定期运行任务。我使用的一个常见模式是让每日cron作业启动任务队列上的任务并进行少量重试(这样如果出现临时故障,它将立即重试)。
如果你确实想使用上面的方法,而不是cron,还有另一件事需要担心:因为你的方法可能因为失败或其他系统问题(例如运行它的实例发生故障)而重试,你应该做确定你最终没有完成两项任务。想象一下,如果它运行,注册下一个任务然后节点发生故障; App Engine将重试,开始第二项任务。为了防止这种情况,您可以使用数据存储(在事务中)来测试并查看下一个任务是否已经入队。类似的东西:
def do_work(counter):
...
@db.transactional
def start_next():
# fetch myModel from the data store here
if myModel.counter == counter:
return # already started next job
myModel.counter = counter
myModel.put()
deferred.defer(do_work, counter + 1, _transactional=True, _countdown=...)
start_next()
注意延迟通话中的“交易”参数;这可确保当且仅当下一个任务入队时才更新MyModel实例。
您可能还希望在一定次数的失败重试后向管理员发送电子邮件。 (您可以在请求HTTP标头中找到它,但如果您想这样做,则不能使用延迟库;您必须直接使用任务队列API。)