Server-sent events with Python,Twisted and Flask: is this a correct approach for sleeping?

Viewed 3933

I started looking at server-sent events and got interested in trying them out with my preferred tools, Python, Flask and Twisted. I'm asking if sleeping the way i'm doing it is fine, compared to the gevent's greenlet.sleep way of doing, this is my very simple code taken and "ported" to Twisted (from gevent):

#!/usr/bin/env python

import random
from twisted.web.server import Site
from twisted.web.wsgi import WSGIResource
from twisted.internet import reactor
import time

from flask import Flask, request, Response
app = Flask(__name__)

def event_stream():
    count = 0
    while True:
        count += 1
        yield 'data: %c (%d)\n\n' % (random.choice('abcde'), count)
        time.sleep(1)


@app.route('/my_event_source')
def sse_request():
    return Response(
            event_stream(),
            mimetype='text/event-stream')


@app.route('/')
def page():
    return '''
<!DOCTYPE html>
<html>
    <head>
        <script type="text/javascript" src="//code.jquery.com/jquery-1.8.0.min.js"></script>
        <script type="text/javascript">
            $(document).ready(
                    function() {
                        sse = new EventSource('/my_event_source');
                        sse.onmessage = function(message) {
                            console.log('A message has arrived!');
                            $('#output').append('<li>'+message.data+'</li>');
                        }

                    })
        </script>
    </head>
    <body>
        <h2>Demo</h2>
        <ul id="output"></ul>
    </body>
</html>
'''


if __name__ == '__main__':
    resource = WSGIResource(reactor, reactor.getThreadPool(), app)
    site = Site(resource)
    reactor.listenTCP(8001, site)
    reactor.run()

Although time.sleep is a blocking function, that will not block the Twisted reactor, and this should be proven by the fact that multiple different browsers can access the page and receive the event properly: using different browsers is needed in case, as Chromium is doing, multiple different requests with the same URI will get queued and since this is a streaming response, that browser queue will be busy until the socket or the request are closed. What are your toughts? Any better way? There is not much sample code about this with Twisted and Flask around..

1 Answers
Related