【问题标题】:How can I use a task queue to perform a long request in Google App Engine如何使用任务队列在 Google App Engine 中执行长请求
【发布时间】:2014-07-30 05:26:01
【问题描述】:

我有一个函数需要很长时间才能从数据存储中删除许多实体。它产生一个 DeadlineExceed 异常。我试图通过一项任务运行它,但我仍然遇到问题。在文档中它说一个任务可以 10 分钟,但同时该任务正在调用一个有其自身限制的端点。因此,我看不到任务 10 分钟执行时间的好处。

我的超过期限的函数是这样写的,它会拉出大约 1000 个实体。

class DeleteJune(webapp.RequestHandler):
    def get(self):
        ji = Junk.all().run()
        for j in ji:
            db.delete(j)

如何运行这样的函数?

【问题讨论】:

    标签: google-app-engine python-2.7


    【解决方案1】:

    App Engine 请求需要在 60 秒内做出响应,否则会给出 DeadlineExceeded 错误。相反,如果您通过任务队列发送请求,它将等待长达 10 分钟的响应。

    任务队列用于命中 url url 处理程序应该运行脚本。因此,从一个请求中,您通过任务队列将任务队列发送到另一个 url:

        from google.appengine.api import taskqueue
        taskqueue.Task(
            url='/your_DeleteJunk_class_url_handler',
            method='post',
            params={'what_to_delete': 'all'}
        ).add(queue_name='some-queue-name-or-default')
    

    您需要 2 个 url 处理程序来执行此操作:一个调用脚本来设置任务队列,另一个由任务队列命中来完成这项工作。

    【讨论】:

    • 谢谢,我不确定您的示例 /your_DeleteJunk_class_url_handler 中的第二个处理程序是否会超过 60 秒。
    • 是的,这就是 10 分钟限制适用的地方。任务队列将等待来自该 url 处理程序的响应长达 10 分钟。
    • 知道了——这很好用。在我的情况下运行大约需要 2 分钟。
    【解决方案2】:

    似乎你想删除所有东西,你可以使用 mapreduce :) 或者使用你提到的任务队列,诀窍是批量删除更快(你的代码正在逐一删除)并链接任务。

    class DeleteJune(webapp.RequestHandler):
        def get(self):
            ji = Junk.all(keys_only=True)
            if not ji.count(1):  # nothing to delete, task is done
                return
            db.delete(ji.run(limit=1000))
            // enqueue same task, or the hacky way just raise 500 here so it will retry :P
    

    上面的代码还没有真正测试过,希望你理解其中的逻辑。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多