Message326628
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>? |
|
Date |
User |
Action |
Args |
2018-09-28 11:36:17 | cjrh | set | recipients:
+ cjrh, asvetlov, docs@python, yselivanov, willingc |
2018-09-28 11:36:17 | cjrh | set | messageid: <1538134577.09.0.545547206417.issue34831@psf.upfronthosting.co.za> |
2018-09-28 11:36:17 | cjrh | link | issue34831 messages |
2018-09-28 11:36:16 | cjrh | create | |
|