在Google App Engine灵活环境中使用stream_with_context在烧瓶中加载栏

时间:2018-07-26 17:00:16

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

用例-一些用户数据正在后端(烧瓶)中加载,并且进度通过加载栏显示在前端。后端有一个生成器,该生成器加载数据并保持 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引擎灵活环境上时,加载栏直接从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

关于如何在Google App Engine上运行它的任何想法吗?

1 个答案:

答案 0 :(得分:1)

根据this documentation,“ EventSource实例打开了与HTTP服务器的持久连接”。根据{{​​3}}提供的说明,该解决方案无法在App Engine中工作:

  

您可以尝试在自己的计算机上声明“ Content-Type:文本/事件流”   自己的原始App Engine处理程序,并使用EventSource

     

here

     浏览器中的

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

     

https://developer.mozilla.org/en-US/docs/Web/API/EventSource   对于java   https://cloud.google.com/appengine/docs/java/requests#Java_Responses   对于python   https://cloud.google.com/appengine/docs/python/requests#Python_Responses   对于PHP   https://cloud.google.com/appengine/docs/php/requests#PHP_Responses   去。

     

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

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

  • 使用https://cloud.google.com/appengine/docs/go/requests#Go_Responses:“ Pusher是一个托管API,用于通过WebSocket向应用程序和其他与Internet连接的设备发送实时双向消息。”这不是官方的产品文档,但其作者是Googler。
  • 如果您使用Pusher:“您可以将App Engine与Firebase实时数据库结合使用,以向浏览器和移动客户端发送即时更新,而无需与服务器的持久流连接或长时间轮询。”

根据Firebase中的消息#231,将很快提供一种更简单的方法。 Flex WebSockets Beta的发布即将推出,但对于标准环境,它距离“至少一年”。如果您想获得有关评论和更新的自动通知,请为issuetracker帖子加注星标。