Skip to content
master
Switch branches/tags
Code

Latest commit

 

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
 
 
 
 
 
 

Fully-functional Event Loop in 100 Lines of Python

Check out the series about the event loop on my blog Explain event loop in 100 lines of code and From Callback Hell to async/await Heaven.

Example using callback-style:

import socket as _socket

class EventLoop: pass

class Context: pass

class socket(Context): pass

def main(serv_addr):
    sock = socket(_socket.AF_INET, _socket.SOCK_STREAM)

    def _on_conn(err):
        if err:
            raise err

        def _on_sent(err):
            if err:
                sock.close()
                raise err

            def _on_resp(err, resp=None):
                sock.close()
                if err:
                    raise err
                print(resp)

            sock.recv(1024, _on_resp)

        sock.sendall(b'foobar', _on_sent)

    sock.connect(serv_addr, _on_conn)

if __name__ == '__main__':
    event_loop = EventLoop()
    Context.set_event_loop(event_loop)

    serv_addr = ('127.0.0.1', int(sys.argv[1]))
    event_loop.run(main, serv_addr)

Give it a try:

# server
> python server.py 53210

# client
> python event_loop.py 53210

Example using async-await-like style:

import socket as _socket

class EventLoop: pass

class Context: pass

class socket(Context): pass

def http_get(sock):
  try:
    yield sock.sendall(b'GET / HTTP/1.1\r\nHost: t.co\r\n\r\n')
    return sock.recv(1024)
  finally:
    sock.close()

def main(serv_addr):
  sock = socket(AF_INET, SOCK_STREAM)
  yield sock.connect(serv_addr)
  resp = yield http_get(sock)
  print(resp)

if __name__ == '__main__':
    event_loop = EventLoop()
    Context.set_event_loop(event_loop)

    serv_addr = ('t.co', 80)
    event_loop.run(main)

Give it a try:

> python event_loop_gen.py 53210

About

Fully-functional Event Loop in 100 Lines of Python

Topics

Resources

Languages