import time
def data_stream():
for i in range(0, 2):
yield 'data: "event"\n\n'.encode('UTF-8')
time.sleep(1)
yield 'data: "closed"\n\n'.encode('UTF-8')
def app(environ, start_response):
if environ.get('PATH_INFO') == '/events':
start_response('200 OK', [
('Content-Type', 'text/event-stream; charset=UTF-8'),
('Cache-Control', 'no-cache'),
('Content-Encoding', 'identity'),
('Transfer-Encoding', 'identity'),
])
return iter(data_stream())
response = "Hello, world!\n\n"
for key, value in environ.items():
response += f" {key}: {value}\n"
status = '200 Hello World'
headers = [
('Content-Type', 'text/plain; charset=UTF-8'),
('Content-Length', str(len(response))),
]
start_response(status, headers)
return iter([ response.encode('UTF-8') ])
gunicorn -b 0.0.0.0:8000 -w 2 app:app
(Note: this is actually horrible because it blocks the workers. I leave it
as an exercise to the reader to figure out an Eventlet/Gevent-based
solution to that.)
(And, BTW, don't @ me, etc: I prefer Eventlet, and in my limited testing
it even proved to perform better than Gevent. You're more likely to
exhaust IP connection ports than to have your application be the bottleneck,
or at least it was so in my extremely synthetic and limited testing!)
# Adventures in Semi-Synchronous WSGI
[PEP 3333][]
```python
import time
def data_stream():
for i in range(0, 2):
yield 'data: "event"\n\n'.encode('UTF-8')
time.sleep(1)
yield 'data: "closed"\n\n'.encode('UTF-8')
def app(environ, start_response):
if environ.get('PATH_INFO') == '/events':
start_response('200 OK', [
('Content-Type', 'text/event-stream; charset=UTF-8'),
('Cache-Control', 'no-cache'),
('Content-Encoding', 'identity'),
('Transfer-Encoding', 'identity'),
])
return iter(data_stream())
response = "Hello, world!\n\n"
for key, value in environ.items():
response += f" {key}: {value}\n"
status = '200 Hello World'
headers = [
('Content-Type', 'text/plain; charset=UTF-8'),
('Content-Length', str(len(response))),
]
start_response(status, headers)
return iter([ response.encode('UTF-8') ])
```
`gunicorn -b 0.0.0.0:8000 -w 2 app:app`
_(Note: this is actually horrible because it blocks the workers. I leave it
as an exercise to the reader to figure out an [Eventlet][]/[Gevent][]-based
solution to that.)_
_(And, BTW, don't @ me, etc: I prefer Eventlet, and in my limited testing
it even proved to perform better than Gevent. You're more likely to
exhaust IP connection ports than to have your application be the bottleneck,
or at least it was so in my extremely synthetic and limited testing!)_
[PEP 3333]: https://www.python.org/dev/peps/pep-3333/
[Eventlet]: http://eventlet.net
[Gevent]: http://www.gevent.org