【问题标题】:Flask in GAE: respond quickly and then do some lengthy workGAE 中的 Flask:快速响应,然后做一些冗长的工作
【发布时间】:2015-01-30 17:32:53
【问题描述】:

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

我找到了流式响应:

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

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

但它没有用。我需要它在它说OK之后关闭请求响应,所以它不会超时。

编辑:原来我还有另一个问题。该代码是应用引擎项目的一部分,因此不允许使用线程。

【问题讨论】:

  • Taskqueues 也许?
  • 如果app.yaml 指定runtime: python27threadsafe: yes,则允许线程。请参阅cloud.google.com/appengine/docs/python/modules/… 以了解可以比产生它们的请求更长的线程。 (尽管正如@SeanVieira 暗示的那样,将任务推送到任务队列通常是一种更好的选择)。

标签: python google-app-engine flask


【解决方案1】:

感谢 Sean Vieira 的 TaskQueue 评论,我在应用引擎中发现了延迟函数。

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

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

【讨论】:

    【解决方案2】:

    您应该使用消息队列(例如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")
    

    【讨论】:

      【解决方案3】:

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

      【讨论】:

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