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

Flask in GAE: respond quickly and then do some lengthy work

我需要快速响应 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 Engine 项目的一部分,因此不允许使用线程。

您应该在请求/响应进程之外使用消息队列(例如Celery or RQ)或线程来运行此任务。

请在回复之前提交任务:

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")

感谢 Sean Vieira 的 TaskQueue 评论,我在 App Engine 中发现了延迟函数。

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

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

我用 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,并且 运行 是任务。我强烈推荐它。