Search code examples
pythongunicornnonblockingserver-sent-eventsgevent

How to configure gunicorn and gevent for sleep function inside a generator for Flask Server-Sent Events?


I'm using this generator function to implement server-sent events:

def event_stream():
    while True:
        gevent.sleep(3)
        yield 'data: some data\n\n'

...and returning it like this:

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

If I use time.sleep(3) instead of gevent.sleep(3), it blocks everything else (as expected). So, when I use gevent and run the Flask app locally, it works fine.

However, when I run it on remote server, it doesn't send messages in 3-second intervals like it did when I ran the app locally, but instead seems to keep on piling up the messages so that when I press Ctrl+C to end the server, all the messages that kept on piling up are dumped at once at the client side.

So, after about 30 seconds of waiting without any messages, when I kill the remote server, the ten messages that should have been received in the 3-second intervals get dumped at once.

I'm assuming this has something to do with how I'm running gunicorn. Here's how I'm currently starting the server:

gunicorn -c config.py server:app -k gevent

The only thing configured inside config file is the bind variable.


Solution

  • After two days of trying out so many things, it turned out that nginx configuration had to be changed for Server-Sent Events.

    Merely adding these three lines did the trick:

    proxy_set_header Connection '';
    proxy_http_version 1.1;
    chunked_transfer_encoding off;
    

    Source: First Google Hit for "nginx server sent events" (SO answer)