【问题标题】:Loading bar in flask using stream_with_context on google app engine flexible environment在谷歌应用引擎柔性环境中使用 stream_with_context 在烧瓶中加载栏
【发布时间】:2019-01-03 18:10:22
【问题描述】:

用例 - 一些用户数据正在后端(烧瓶)中加载,进度通过加载栏显示在前端。后端有一个生成器,它加载数据并保持 yielding 进度(这个生成器使用 stream_with_context 作为响应返回)。前端使用 javascript EventSource 对象查询烧瓶视图。

代码:

@app.route("/progress", methods=['GET'])
def progress():
    gen = get_user_data()
    return Response(stream_with_context(gen), mimetype= 'text/event-stream')

def get_user_data():
    n = 100 (number of data points to be loaded)
    for i in range(1,n+1):
        #load data
        yield "data:" + str((float(i)/(n))*100) + "\n\n"
    yield "data:" + "close" + "\n\n"

这在我的本地环境中运行良好。但是,当我将它部署在 google app engine 柔性环境上时,加载栏直接从 0 变为 100。也就是说,每次生成器产生时,前端都不会更新,而是得到一次所有的 EventSource 消息(当生成器完成执行时)。

我的 app.yaml:

runtime: python
env: flex
entrypoint: gunicorn --timeout 240 -b :$PORT app:app

runtime_config:
  python_version: 2

manual_scaling:
  instances: 1

resources:
  cpu: 1
  memory_gb: 0.5
  disk_size_gb: 10

知道如何让它在谷歌应用引擎上运行吗?

【问题讨论】:

    标签: python google-app-engine flask generator gunicorn


    【解决方案1】:

    根据this documentation,“EventSource 实例打开到 HTTP 服务器的持久连接”。根据here提供的解释,此解决方案在 App Engine 中不起作用:

    您可以尝试在您的 拥有原生 App Engine 处理程序,并使用 EventSource

    https://developer.mozilla.org/en-US/docs/Web/API/EventSource

    浏览器中的对象以启动保持活动连接。问题 也就是说,App Engine 等待您的应用程序上的处理程序到 return fully before flushing the buffer and sending the response data。你可以找到 这记录在这里:

    https://cloud.google.com/appengine/docs/java/requests#Java_Responses 对于java https://cloud.google.com/appengine/docs/python/requests#Python_Responses 对于蟒蛇 https://cloud.google.com/appengine/docs/php/requests#PHP_Responses 为 php https://cloud.google.com/appengine/docs/go/requests#Go_Responses 去。

    这实际上意味着您的信息流不会 “保持活动状态”,并且每次发送一个响应时都会关闭。或者,如果你 像大多数人一样在服务器端实现服务器发送的事件代码, 它会缓冲所有的响应,最后只发送它们 当它终止时。

    目前有几种复杂的解决方法:

    • 使用Pusher:“Pusher 是一个托管 API,用于通过 WebSockets 向应用程序和其他互联网连接设备发送实时双向消息。”这不是官方产品文档,但其作者是 Google 员工。
    • 如果您使用 Firebase:“您可以将 App Engine 与 Firebase 实时数据库结合使用,以向浏览器和移动客户端发送即时更新,而无需与服务器建立持久的流连接或长轮询。”

    根据this issuetracker 中的消息#231,很快就会有一种更简单的方法可用。 Flex WebSockets Beta 版即将推出,但对于标准环境,“至少还需要一年时间”。如果您想获得有关 cmets 和更新的自动通知,请在 issuetracker 帖子上加注星标。

    【讨论】:

    • 感谢您的详细解答!我决定继续使用此答案中提到的方法:stackoverflow.com/questions/9240597/… 方法是:使用任务队列设置数据加载的进度,并从我的客户端轮询或使用通道 API 使客户端能够获取更新,而不是使用 javascript 的 EventSource。
    • 我已经看过那篇文章并检查了 October 2017 上已弃用 Channel API,因为该帖子的日期是 2012 年。我不确定任务队列是否有可能,但祝你好运!跨度>
    猜你喜欢
    • 2020-11-05
    • 1970-01-01
    • 2023-03-15
    • 2021-04-12
    • 1970-01-01
    • 2016-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多