This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author cjrh
Recipients asvetlov, cjrh, docs@python, willingc, yselivanov
Date 2018-09-28.11:36:16
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1538134577.09.0.545547206417.issue34831@psf.upfronthosting.co.za>
In-reply-to
Content
Hi Yury,

As discussed, below is a very rough outline of a proposed TOC for an asyncio tutorial. No content has been written yet (only what you see below). I think we should nail down the TOC first.

Asyncio Tutorial
================

Proposed Table of Contents:

- Why asyncio?
    - Reason #1: thread safety by not using threads at all.
    - Reason #2: very many concurrent socket connections, which threads
      make cumbersome.
    - Demo: concurrency without threads
        - (only goals here are to *briefly* introduce the syntax, and then
          demonstrate concurrency without threads)
        - show two tasks, one prints out integers 0-9, while the other
          prints out letters of the alphabet, A-I.
        - pose the question: "they're running concurrently but we're
          not using threads: how is that possible?"
        - explain that there is a thing called an "event loop" behind
          the scenes that allows execution to switch between the two
          every time one of them "waits".
        - emphasize that you can easily spot where the switch can happen,
          it is where you see the "await" keyword. Switches will occur
          nowhere else.

- The difference between functions and `async def` functions
    - async & await
        - show `async def` functions, compare to `def` functions.  
        - use inspect module to show what things actually are, e.g. function,
          coroutine function, coroutine, generator function, generator,
          asynchronous generator function, asynchronous generator.
        - point out you can only use "await" inside an async def fn
        - point out that `await <x>` is an expression, and you can
          use it in most places any other expression can be used.

- How to run `async def` functions
    - point out there are two different issues: (a) `async def` functions
      can call other functions, and other `async def` functions using
      `await`, but also, (b) how to "get started" with the first
      `async def` function? Answer: run the event loop.
    - show `asyncio.run()`, in particular running an `async def main()`
      function, which itself can call others.

- Dealing with concurrent functions
    - (This is maybe too similar to the new docs in the section
      https://docs.python.org/3/library/asyncio-task.html?highlight=asyncio%20run#coroutines-and-tasks)
    - What if you want to run an `async def` function, but you don't
      want to wait for it? Answer: create a "task" for it.
    - What if you want to run multiple functions concurrently, and you
      do want to wait for all of them to finish? Answer: use `gather`
      or `wait()`

- Case Study: chat server/client (my proposal)
    - (goal is to walk through building a realistic example of using 
      asyncio)
    - (This will be a lot more fun than a web-crawler. Web-crawlers are
      super boring!)
    - (I'm pretty confident the size of the code can be kept small. A 
      lot can be done in under 50 lines, as I showed in the case studies
      in my book)
    - server uses streams API
    - server receives many long-lived connections
    - user can create/join a "room", and then start typing messages.
      Other connected clients in the same room will see the messages.
    - client implementation has some options:
        - could use Tkinter gui, using streams API in an event loop 
          on a separate thread. (This would show how asyncio isn't some 
          alien thing, but is part of python. Would also show how to 
          set up asyncio to work in a separate thread. Finally, would not
          require any external dependencies, only the stdlib is needed
          for the entire case study.)
        - could use a browser client, connecting back to the server 
          over a websocket connection. (This might seem simpler, but 
          in fact introduces a lot more complexity than just using
          tkinter. We need to bring in html, css, probably some js and
          probably also a third-party websockets python library. I feel
          like it isn't a good fit for a stdlib python tutorial, but it 
          is a more modern approach.)
        - there are not a lot of other options. terminal-based client 
          might be possible, but probably hard, not cross-platform, and 
          will be unappealing to many people. 
    - When describing the code, point out:
        - you have to choose a "message protocol" (size-prefixed is fine)
        - you must put `send` and `recv` in separate tasks
        - server will "keep track" of connected clients and the room
          (or rooms?) they've joined
        - startup and shutdown, specific references to the new `run()`
          function
        - <others>?
History
Date User Action Args
2018-09-28 11:36:17cjrhsetrecipients: + cjrh, asvetlov, docs@python, yselivanov, willingc
2018-09-28 11:36:17cjrhsetmessageid: <1538134577.09.0.545547206417.issue34831@psf.upfronthosting.co.za>
2018-09-28 11:36:17cjrhlinkissue34831 messages
2018-09-28 11:36:16cjrhcreate