I have multiple clients trying to connect to a server sent events stream at /stream
. This works with a single client, but attempting to connect any more clients results in the new client becoming indefinitely blocked waiting for data. If I send more data, it only goes to the first client, and no others.
Here is a small snippet that illustrates my problem:
import flask
import time
app = flask.Flask(__name__)
def event_stream():
for i in xrange(9999):
yield "data: %d\n\n" % i
time.sleep(1)
@app.route("/stream", methods=[ "GET" ])
def stream():
return flask.Response(
event_stream(),
mimetype="text/event-stream"
)
I then run this with gunicorn --worker-class=gevent -w 4 -t 99999 app:app
. It works for a single client, but any others get blocked when issuing GET /stream
.
What is the cause of the block, and how should I fix it?
I debugged a little more and got some strange results. If I do this procedure, then this happens:
It turns out that this is something to do with the Chromium web browser, where I was testing. It holds back on making the request until the first one completes, for some reason. Using curl
, or an incognito browser session allowed multiple sessions to run at the same time. This means that my problem doesn't really exist in reality, it just appears that way because of the way that Chromium handles simultaneous requests to the same resource.
I'm not sure quite why Chromium behaves this way, it seems weird. Either way, this isn't a real problem, only a perceived one by my browser.
I was getting similar results in Firefox (as I noted in the comments) then I switched to using WSGIServer in the main block instead of gunicorn and everything works, the timeout is gone (because WSGIServer doesn't timeout its workers but gunicorn does) so I thought this made it worth adding as an answer.
Add this:
if __name__ == '__main__':
http_server = WSGIServer(('127.0.0.1', 8001), app)
http_server.serve_forever()
Then just do
python app.py
[I would not have had a timeout after 30s if I had used Chris' command line and set timeout to 99999 but there would have been much later]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With