我需要快速响应烧瓶中的请求,然后在之后执行冗长的(可能是多分钟的)任务。
我找到了流媒体响应:
@app.route('/new_data_notification', methods=['GET', 'POST'])
def push_data():
...
def stream():
yield "OK"
updateData()
return Response(stream(), mimetype="text/plain")
但它不起作用。 我需要它在OK
之后关闭请求响应,因此它不会超时。
答案 0 :(得分:1)
感谢Sean Vieira的TaskQueue评论,我在app引擎中找到了延迟函数。
from google.appengine.ext import deferred
deferred.defer(my_func, arg0, arg1, ...)
在使用提供的参数调用函数之前,这基本上等待一个未知的时间,通常不到几分钟。效果很好,不需要线程。只需确保my_func
和所有参数都是可挑选的,并且您不依赖于修改您的应用程序的工作路径(这部分)。
答案 1 :(得分:0)
您应该使用消息队列(例如Celery或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")
答案 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,并运行任务。我强烈推荐它。