async python

 

tuna vargi

software developer @ hipo

async code is more efficient but maybe harder

parallelism

Use multiple processors to make computation faster

concurrency

permit multiple tasks to proceed without waiting for each other

is python supports async code

python threads

  • Python uses real system threads
  • POSIX threads
  • Fully managed by operating system

Global Interpreter Lock

  • Parallel execution is blocked
  • Only one thread for one interpreter
  • Simplifies many low-level details(Memory management etc)

thread execution

  • When a thread is running, it holds the GIL
  • GIL released on I/O (read,write,send,recv,etc.)

concurrency problem

  • Multiple Processes
  • Threads
  • Green Threads
  • Asynchronous programming

asynchronous 
programing

event loop
&
reactor pattern

Python implementations

  • Tornado
  • Twisted
  • AsyncIO

Tornado Example
python2

class GenAsyncHandler(RequestHandler):
    @gen.coroutine
    def get(self):
        http_client = AsyncHTTPClient()
        response = yield http_client.fetch("http://example.com")
        do_something_with_response(response)
        self.render("template.html")

Tornado Periodic Callback

asyncio

PEP 3156

Coroutine

  • generator function may receive parameters
  • decorated with @couroutine

 

 

Future

  • promise of a result or an error 

 

 

Task

  • Future which runs on a coroutine    

 

which prevents sequential coding

"yield from" keeps the sequential style

Generators calling other generators, generator delegation.

 

to remove callbacks

sequential query

async query with callback

 


def get(self):
    def on_result(result):
        self.write(result)
    make_the_query(callback=on_result)
def get(self)
    result = make_the_query()
    self.write(result)

async query with sub-generator

def get(self)
    result = yield from make_the_query()
    self.write(result)

Future object

  • Just a placeholder which going to be a real object when it will be ready
  • Like JS promise, defer

 

f.result()

f.exception()

f.done() f.cancel()

Title Text

Subtitle

@asyncio.coroutine
def print_page(url):
    response = yield from aiohttp.request('GET', url)
    body = yield from response.read_and_close(decode=True)
    print(body)

loop.run_until_complete(asyncio.wait([print_page('http://example.com/foo'),
                                      print_page('http://example.com/bar')]))

Parallel Tasks

import asyncio

@asyncio.coroutine
def factorial(name, number):
    f = 1
    for i in range(2, number+1):
        print("Task %s: Compute factorial(%s)..." % (name, i))
        yield from asyncio.sleep(1)
        f *= i
    print("Task %s: factorial(%s) = %s" % (name, number, f))

loop = asyncio.get_event_loop()
tasks = [
    asyncio.ensure_future(factorial("A", 2)),
    asyncio.ensure_future(factorial("B", 3)),
    asyncio.ensure_future(factorial("C", 4))]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()

result

compatibility

semi compatible with tornado and twisted

THANKS

AsyncIO

By Tuna Vargı

AsyncIO

  • 1,594