Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Python and Asynchrony

Python and Asynchrony

Presented at Jobspace on 14 October, 2016.

An introduction to asynchrony programming in Python. This presentation consists of two parts: First I introduce the idea behind asynchrony, and how it differs from more “traditional” (in Python sense) concurrent solutions.

In the second part I use code examples to walk through the development of async paradigms, introducing async through callbacks, promises, and finally coroutine, so we get a deeper understanding how the underlying plumbing works when you run an async program.

Code examples for the second part of the presentation can be found at http://bit.ly/asyncio-examples.

Tzu-ping Chung

October 14, 2016
Tweet

More Decks by Tzu-ping Chung

Other Decks in Programming

Transcript

  1. Quick Questions • Concurrency with Python • Threads and multi-processing

    • Single-thread asynchrony • asyncio, Twisted, Tornado, etc.
  2. Threads • More than you need • Race conditions •

    Dead-locking • Resource starvation
  3. Multitasking • A common OS problem • More tasks than

    threads • Cooperative • Pre-emptive
  4. import asyncio # Init code goes here. def print_and_exit(): print('Hello

    asyncio!') asyncio.get_event_loop().stop() loop = asyncio.get_event_loop() loop.call_soon(print_and_exit) loop.run_forever()
  5. Pyramid of Doom $(function () { $("button").click(function (e) { $.get(URL,

    function (data) { $(".list").each(function () { $(this).click(function () { setTimeout(function () { alert("Top of the world"); }, 1000); }); }); }); }); });
  6. def send_repos_request(): ... task = ... task.add_done_callback(...) def read_repos(future): ...

    = future.result() ... task = ... task.add_done_callback(...) def send_forked_repo_requests(future): ... = future.result() ... task = ... task.add_done_callback(...) def read_forked_repos(future): ... = future.result() ... task = ... task.add_done_callback(...)
  7. async def run(session): response = await send_repos_request(session) try: data =

    await read_repos(response) except APIError: return responses = await send_forked_repo_requests(session, data) datasets = await read_forked_repo_requests(responses) print_source_names(datasets)
  8. async def run(session): response = await send_repos_request(session) try: data =

    await read_repos(response) except APIError: return responses = await send_forked_repo_requests(session, data) datasets = await read_forked_repo_requests(responses) print_source_names(datasets)
  9. Everything Has a Counterpart • async def / await •

    async with • async for (Python 3.6)
  10. class AsyncContextManager: async def __aenter__(self): await log('entering context') async def

    __aexit__(self, exc_type, exc, tb): await log('exiting context')
  11. class AsyncIterable: def __aiter__(self): return self async def __anext__(self): data

    = await ... if data: return data else: raise StopAsyncIteration
  12. Further Watching • A gentle introduction to asyncio • What

    in the World is Asyncio? • Topics of Interest (Python Asyncio) • You Might Not Want Async • and more…!