在 Google App Engine 中安排运行超过 10 分钟的任务的最佳方式是什么?
What's the best way of scheduling a task that runs over ten minutes in Google App Engine?
假设我有一个 运行 一个小时的脚本。它所做的只是休眠一个小时,然后在该小时结束时更改数据存储中的某些内容。
def task(keyname):
time.sleep(3600)
q = Item.all()
item = q.filter("keyname = ", "%s" % keyname).get()
item.value += 1
item.put()
完成此任务的最佳方法是什么?
cron 文档说 "an HTTP request invoked by cron can run for up to 10 minutes, but is subject to the same limits as other HTTP requests." 我假设这意味着 运行 超过十分钟的 cron 任务将会中断。
我查看了任务队列文档,但我不想将这些任务一个接一个地排入队列。我希望它们同时发生。
我正在考虑添加一个计数器 属性 并且 运行 每分钟执行一次任务而不是休眠:
def task(keyname):
q = Item.all()
item = q.filter("keyname = ", "%s" % keyname).get()
if item.counter == 60:
item.value += 1
item.put()
else:
item.counter += 1
item.put()
但是访问数据库的次数太多了。
那么,有人有更聪明的解决方法吗?
当你说你希望 "these tasks" 同时发生时,我不明白你的意思;你只提到了一个任务。
无论如何,任务队列是执行此操作的方法。您可以使用 Task 构造函数的 countdown
参数来告诉它在 3600 秒后执行。
我通常更喜欢使用 deferred
library,它可以动态创建任务而无需设置特定的处理程序:
from google.appengine.ext import deferred
...
deferred.defer(my_task, _countdown=3600)
cron 作业命中一个处理程序,此处理程序启动一个任务。这个过程通常需要不到一秒钟的时间。之后,只要您需要,任务就可以 运行 - 永远,如果需要的话。这完全取决于 on the target of a task。 10 分钟限制仅适用于前端(F 型)实例。
如有必要,您可以 运行 同时执行多项任务。
@Soricidae,您正在构建一个 cron 任务。
- 为此,您需要有一个处理程序来调用您的方法 task。
- 此外,您需要指定 URL 到该处理程序的路由。
- 然后您需要在 cron.yaml 中指定一个 cronjob 调用 task 方法。
*。此外,我强烈建议使用任务队列,以便应用引擎在 cron 任务期间解决您的加载时间问题。
例如,在我的例子中,我有一个向用户发送电子邮件的欢迎处理程序,每 24 小时检查一次是否有超过 1 天的新用户尚未受到欢迎...
所以,我定义了以下路由(1 个用于 cronjob,1 个用于 taskqueue):
RedirectRoute('/cronjob-welcome/', handlers.WelcomeCronjobHandler, name='cronjob-welcome', strict_slash=True),
RedirectRoute('/taskqueue-welcome/', handlers.WelcomeHandler, name='taskqueue-welcome', strict_slash=True),
然后,我定义了一个 cronjob 处理程序,一旦调用它就作为任务队列用于真正的操作处理程序,请参阅:
class WelcomeCronjobHandler(BaseHandler):
def get(self):
welcome_url = self.uri_for('taskqueue-welcome')
taskqueue.add(url=welcome_url, params={
'offset': 0
})
您可以看到此处理程序请求 welcome_url,它调用路由中定义的处理程序 taskqueue-welcome 并执行以下操作:
class WelcomeHandler(BaseHandler):
"""
Core Handler for sending users welcome message
Use with TaskQueue
"""
@taskqueue_method
def post(self):
# ... MY CODE FOR EMAILING USERS ....
# ... YOUR CODE SHOULD GO IN HERE ...
最后,为了每 24 小时调用一次 cronjob 处理程序,在我的 cron.yaml 文件中添加了以下内容,注意 cronjob-welcome[=50 的路由=]:
- description: welcome messaging
url: /cronjob-welcome/
schedule: every day 13:00
总结一下,我的 cron.yaml 每天在 13:00 小时调用 cronjob 处理程序,它在同时触发一个 taskqueue handler,调度一个 google appengine taskqueue 解决 my scheduled task.
希望对您有所帮助。
假设我有一个 运行 一个小时的脚本。它所做的只是休眠一个小时,然后在该小时结束时更改数据存储中的某些内容。
def task(keyname):
time.sleep(3600)
q = Item.all()
item = q.filter("keyname = ", "%s" % keyname).get()
item.value += 1
item.put()
完成此任务的最佳方法是什么?
cron 文档说 "an HTTP request invoked by cron can run for up to 10 minutes, but is subject to the same limits as other HTTP requests." 我假设这意味着 运行 超过十分钟的 cron 任务将会中断。
我查看了任务队列文档,但我不想将这些任务一个接一个地排入队列。我希望它们同时发生。
我正在考虑添加一个计数器 属性 并且 运行 每分钟执行一次任务而不是休眠:
def task(keyname):
q = Item.all()
item = q.filter("keyname = ", "%s" % keyname).get()
if item.counter == 60:
item.value += 1
item.put()
else:
item.counter += 1
item.put()
但是访问数据库的次数太多了。
那么,有人有更聪明的解决方法吗?
当你说你希望 "these tasks" 同时发生时,我不明白你的意思;你只提到了一个任务。
无论如何,任务队列是执行此操作的方法。您可以使用 Task 构造函数的 countdown
参数来告诉它在 3600 秒后执行。
我通常更喜欢使用 deferred
library,它可以动态创建任务而无需设置特定的处理程序:
from google.appengine.ext import deferred
...
deferred.defer(my_task, _countdown=3600)
cron 作业命中一个处理程序,此处理程序启动一个任务。这个过程通常需要不到一秒钟的时间。之后,只要您需要,任务就可以 运行 - 永远,如果需要的话。这完全取决于 on the target of a task。 10 分钟限制仅适用于前端(F 型)实例。
如有必要,您可以 运行 同时执行多项任务。
@Soricidae,您正在构建一个 cron 任务。
- 为此,您需要有一个处理程序来调用您的方法 task。
- 此外,您需要指定 URL 到该处理程序的路由。
- 然后您需要在 cron.yaml 中指定一个 cronjob 调用 task 方法。
*。此外,我强烈建议使用任务队列,以便应用引擎在 cron 任务期间解决您的加载时间问题。
例如,在我的例子中,我有一个向用户发送电子邮件的欢迎处理程序,每 24 小时检查一次是否有超过 1 天的新用户尚未受到欢迎...
所以,我定义了以下路由(1 个用于 cronjob,1 个用于 taskqueue):
RedirectRoute('/cronjob-welcome/', handlers.WelcomeCronjobHandler, name='cronjob-welcome', strict_slash=True),
RedirectRoute('/taskqueue-welcome/', handlers.WelcomeHandler, name='taskqueue-welcome', strict_slash=True),
然后,我定义了一个 cronjob 处理程序,一旦调用它就作为任务队列用于真正的操作处理程序,请参阅:
class WelcomeCronjobHandler(BaseHandler):
def get(self):
welcome_url = self.uri_for('taskqueue-welcome')
taskqueue.add(url=welcome_url, params={
'offset': 0
})
您可以看到此处理程序请求 welcome_url,它调用路由中定义的处理程序 taskqueue-welcome 并执行以下操作:
class WelcomeHandler(BaseHandler):
"""
Core Handler for sending users welcome message
Use with TaskQueue
"""
@taskqueue_method
def post(self):
# ... MY CODE FOR EMAILING USERS ....
# ... YOUR CODE SHOULD GO IN HERE ...
最后,为了每 24 小时调用一次 cronjob 处理程序,在我的 cron.yaml 文件中添加了以下内容,注意 cronjob-welcome[=50 的路由=]:
- description: welcome messaging
url: /cronjob-welcome/
schedule: every day 13:00
总结一下,我的 cron.yaml 每天在 13:00 小时调用 cronjob 处理程序,它在同时触发一个 taskqueue handler,调度一个 google appengine taskqueue 解决 my scheduled task.
希望对您有所帮助。