[openstack-dev] Asynchrounous programming: replace eventlet with asyncio

victor stinner victor.stinner at enovance.com
Tue Feb 4 17:55:39 UTC 2014


Hi,

> Thanks for taking this on, Victor.
> 
> Do you have a small eventlet program example that you can show the
> transformation to asyncio?

Example getting the body of an HTML page and display it to the terminal. The HTTP query is invalid, the Host header is missing, but supporting HTTP/1.0 and the connected mode would make the example more complex.

Eventlet version:
---
import eventlet
from eventlet.green import socket

def getbody(url, limit=1024):
    c = socket.socket()
    ip = socket.gethostbyname(url)
    c.connect((ip, 80))
    c.sendall('HEAD /\r\n\r\n')
    body = c.recv(limit)
    return body

body = getbody('www.python.org')
print(body)
---

Trollius version:
---
import asyncio
import logging; logging.basicConfig()
from asyncio import Return
import socket

@asyncio.coroutine
def getbody(url):
    reader, writer = yield asyncio.open_connection(url, 80)
    writer.write('HEAD /\r\n\r\n')
    # yield writer.drain()
    body = yield reader.read()
    raise Return(body)

loop = asyncio.get_event_loop()
body = loop.run_until_complete(getbody('www.python.org'))
print(body)
loop.close()
---

Remarks:

 - no special "sendall" method: writer.write() always write all data, and it's the same name for any kind of transport (socket, SSL socket, pipe, etc.)
 - open_connection() accepts directly an hostname. It resolves the hostname asynchronously (call socket.gethostbyname in a pool of threads)
 - it's possible to call reader.read() with no limit: in this case, read() stops when the server closes the connection. Using eventlet, you have to buffer manually. There is also a convinient readline() buffer which reads until it gets a newline character ("\n")
 - run_until_complete() is only used in short examples, usually run_forever() is preferred, something will call loop.stop() to stop the loop

You can uncomment "writer.drain()" to wait until all data are sent to the server. Otherwise, it will be done in background asynchronously.

See asyncio documentation for more examples:
http://docs.python.org/dev/library/asyncio.html

Victor



More information about the OpenStack-dev mailing list