GAE中的烧瓶:快速响应,然后做一些冗长的工作

时间:2015-01-30 17:32:53

标签: python google-app-engine flask

我需要快速响应烧瓶中的请求,然后在之后执行冗长的(可能是多分钟的)任务。

我找到了流媒体响应:

@app.route('/new_data_notification', methods=['GET', 'POST'])
def push_data():
...
def stream():
    yield "OK"
    updateData()

return Response(stream(), mimetype="text/plain")

但它不起作用。 我需要它在OK之后关闭请求响应,因此它不会超时。

编辑:结果我有另一个问题。代码是app引擎项目的一部分,因此不允许进行线程化。

3 个答案:

答案 0 :(得分:1)

感谢Sean Vieira的TaskQueue评论,我在app引擎中找到了延迟函数。

from google.appengine.ext import deferred
deferred.defer(my_func, arg0, arg1, ...)

在使用提供的参数调用函数之前,这基本上等待一个未知的时间,通常不到几分钟。效果很好,不需要线程。只需确保my_func和所有参数都是可挑选的,并且您不依赖于修改您的应用程序的工作路径(这部分)。

答案 1 :(得分:0)

您应该使用消息队列(例如CeleryRQ)或线程在请求​​/响应过程之外运行此任务。

只需在回复您的回复之前提交任务:

import threading

@app.route('/new_data_notification', methods=['GET', 'POST'])
def push_data():

def stream():
    # Using threads
    threading.Thread(target=updateData).start()
    # Or, using RQ
    # q.enqueue(updateData)
    return Response("OK", mimetype="text/plain")

答案 2 :(得分:0)

我将Taskqueue用于此类事情。这很容易。听起来令人生畏,但事实并非如此。与用户请求不同,在任务队列中运行的任务不受限制为60秒的时间限制。

例如 - 这是控制器代码,它触发我在队列中运行的blob解析任务:

  blobparser_queue = taskqueue.Queue('blobparser')
  new_task = taskqueue.Task(url='/task/parse_blob/', params={'account_id': account_id,'blob_id': str(blobresource_id)},method='GET')
  blobparser_queue.add(new_task)

这会在我的命名队列blobparser中添加一个新任务。它将所有这些参数传递给提供的URL,并运行任务。我强烈推荐它。