Intro to Gevent – Coroutine-based concurrency library for Python – Why Coroutine?



Intro to Gevent – Coroutine-based concurrency library for Python – Why Coroutine?

0 0


gevent-slides

Slides for introduction to gevent

On Github 2359media / gevent-slides

Intro to Gevent

Coroutine-based concurrency library for Python

Heads Up

It uses greenlet on top of the libevent event loop.

Version 1.0.x will be based on libev, and there's an alternative: uvent that is based on libuv (used by node.js).

Latest version is based on libev, and there's an alternative implementation called uvent, based on libuv (used by node.js).

Why Coroutine?

Coroutines are all colleagues!

Subroutines or methods or functions?

Drones controlled by a master

More on Coroutine

Couroutine Tutorial

SICP at Berkeley: Sequences and Coroutines

PyCon 2011: An outsider's look at co-routines

That's it, let's go back to gevent.

Projects using gevent

  • gunicorn
  • ultramysql
  • ultramemcache
  • gevent-memcache
  • geventhttpclient
  • gevent-socketio
  • gTornado
  • gevent-zeromq
  • locust

and a lot more...

A basic sample code

import gevent

def foo():
    print('Running in foo')
    gevent.sleep(0)
    print('Explicit context switch to foo again')

def bar():
    print('Explicit context to bar')
    gevent.sleep(0)
    print('Implicit context switch back to bar')

def coo():
    print('Explicit context to coo')
    gevent.sleep(0)
    print('Implicit context switch back to coo')

def doo():
    print('Explicit context to doo')
    gevent.sleep(0)
    print('Implicit context switch back to doo')

Output of the code

Running in foo
Explicit context to bar
Explicit context to coo
Explicit context to doo
Explicit context switch to foo again
Implicit context switch back to doo
Implicit context switch back to coo
Implicit context switch back to bar

Let's modify the sleep period

import gevent

def foo():
    print('Running in foo')
    gevent.sleep(0)
    print('Explicit context switch to foo again')

def bar():
    print('Explicit context to bar')
    gevent.sleep(15)
    print('Implicit context switch back to bar')

def coo():
    print('Explicit context to coo')
    gevent.sleep(0)
    print('Implicit context switch back to coo')

def doo():
    print('Explicit context to doo')
    gevent.sleep(20)
    print('Implicit context switch back to doo')

gevent.joinall([
    gevent.spawn(foo),
    gevent.spawn(bar),
    gevent.spawn(coo),
    gevent.spawn(doo)
])

Sequence changes based on the period of sleep (busy time)

Running in foo
Explicit context to bar
Explicit context to coo
Explicit context to doo
Explicit context switch to foo again
Implicit context switch back to coo
Implicit context switch back to bar
Implicit context switch back to doo

Let's visualize it

A basic HTTP server

"""HTTP server example.

Uses libevent API directly and thus may be dangerous.
WSGI interface is a safer choice, see examples/wsgiserver.py.
"""
from gevent import http

def callback(request):
    print request
    if request.uri == '/':
        request.add_output_header('Content-Type', 'text/plain')
        request.send_reply(200, "OK", 'Hello World!')
    else:
        request.add_output_header('Content-Type', 'text/plain')
        request.send_reply(404, "Not Found", "Not Found")

print 'Serving on 8088...'
http.HTTPServer(('0.0.0.0', 8088), callback).serve_forever()

WSGI server

from gevent.pywsgi import WSGIServer

def application(environ, start_response):
    status = '200 OK'

    headers = [
        ('Content-Type', 'text/html')
    ]

    start_response(status, headers)
    yield "<p>Hello"
    yield "World</p>"

WSGIServer(('', 8000), application).serve_forever()

That's all

Stellar Links