【问题标题】:Loading an eventstream through Gunicorn + Flask通过 Gunicorn + Flask 加载事件流
【发布时间】:2015-05-24 03:21:16
【问题描述】:

我正在尝试使用 Flask 应用程序生成大型 PDF。 pdf 生成涉及生成十个长 pdf,然后将它们合并在一起。该应用程序使用带有标志的 Gunicorn 运行:--worker-class gevent --workers 2。

这是我的服务器端代码的样子:

@app.route ('/pdf/create', methods=['POST', 'GET'])
def create_pdf():
    def generate():
        for section in pdfs:
            yield "data: Generating %s pdf\n\n" % section
            # Generate pdf with pisa (takes up to 2 minutes)

        yield "data:  Merging PDFs\n\n"
        # Merge pdfs (takes up to 2 minutes)
        yield "data: /user/pdf_filename.pdf\n\n"

    return Response(stream_with_context(generate()), mimetype='text/event-stream')

客户端代码如下:

var source = new EventSource(create_pdf_url);
source.onopen = function (event) {
  console.log("Creating PDF")
}
source.onmessage = function (event) {
    console.log(event.data);
}
source.onerror = function (event) {
    console.log("ERROR");
}

当我不使用 GUnicorn 运行时,我会从控制台日志中获得稳定的实时更新。它们看起来像:

Creating PDF
Generating section one
Generating section two
Generating section three
...
Generating section ten
Merging PDFS
/user/pdf_filename.pdf

当我使用 Gunicorn 运行此代码时,我没有得到定期更新。工作人员一直运行直到 Gunicorn 的超时将其杀死,然后我得到所有应该发生的消息的转储,然后是最终错误

Creating PDF
Generating section one
Generating section two
ERROR

Gunicorn 日志如下所示:

[2015-03-19 21:57:27 +0000] [3163] [CRITICAL] WORKER TIMEOUT (pid:3174)

如何防止 Gunicorn 终止进程?我认为设置超大超时不是一个好主意。也许 gunicorn 的工人阶级中有一些东西可以用来确保正确处理流程?

【问题讨论】:

  • 第二个source.onmessage应该是source.onerror,但可能与解决方案无关。
  • 好收获。编辑以修正错字。

标签: python flask gunicorn gevent event-stream


【解决方案1】:

我最终用 Celery 解决了这个问题。

我使用this example 来指导我设置 Celery。

然后我使用Grinberg's Celery tutorial 将实时更新流式传输到用户的浏览器。

【讨论】:

    猜你喜欢
    • 2019-12-27
    • 2022-01-04
    • 1970-01-01
    • 2020-08-20
    • 2016-07-20
    • 1970-01-01
    • 2017-11-12
    • 2018-10-09
    • 1970-01-01
    相关资源
    最近更新 更多