Andrew Svetlov
@andrew_svetlov
andrew.svetlov@gmail.com
https://asvetlov.github.io/pycon-ru-2018/
Microservices
Websockets
Non-HTTP transports
Long-running tasks
A kind of concurrent programming
asyncio task is a lightweight thread
Utilize the knowledge of multithreaded approach
Use locks, events, queues etc
No lowlevel API
A way to speed up Django app
def view(request):
loop = asyncio.get_event_loop()
tasks = [asyncio.create_task(fetch(url))
for url in urls]
loop.run_until_complete(asyncio.wait(tasks))
Don't mix sync and async code
async def process(url):
...
async def process_all():
for url in urls:
asyncio.create_task(process(url))
aiojobs
class Cls:
def __init__(self):
self.client = aiohttp.ClientSession()
class Cls:
def __init__(self):
self.client = None
@classmethod
async def create(cls):
self = cls()
self.client = await aiohttp.ClientSession()
obj = await Cls.create()
async def fetch(db):
cursor = await db.execute("SELECT * from tbl")
ret = []
async for rec in cursor:
ret.append(rec)
return ret # What happens with the cursor?
__del__
await obj.close()
async with obj: ...
async with aiohttp.ClientSession() as session:
async with session.get(url) as resp:
body = await resp.text()
Hint: reuse client sessions
Hint2: await session.close()
timeout = aiohttp.ClientTimeout(
total=60,
connect=15)
async with session.get(url, timeout=timeout): ...
async def handler(request):
resp = web.WebSocketResponse()
await resp.prepare(request)
await resp.send_str('Welcome!')
async for msg in resp:
await process(msg.data)
try:
async for msg in resp:
# process msg
finally:
# disconnected
Ping a peer, dude
async def handler(request):
await request.config['db'].execute("UPDATE ...")
return web.Response(text="OK")
async def handler(request):
await asyncio.shield(request.config['db'].execute("UPDATE ..."))
return web.Response(text="OK")
from module import db
await db.execute(...)
Problems: testing, configuration etc
async def init(app):
app['config'] = await load_config()
app['db'] = await create_db(app['config'])
yield
await app['db'].close()
app = web.Application()
app.cleanup_ctx.append(init)
async def handler(request):
await app.config_dict['db'].execute('SELECT 42')
...
class Bad(aiohttp.ClientSession):
async def query(self, url):
...
class Good:
def __init__(self):
self._client = aiohttp.ClientSession()
async def close(self):
await self._client.close()
async def query(self, url):
async with self._client.get(url) as resp:
return await self._process(resp)
async def bad(request):
request.app.my_attr[key] = value
async def good(request):
request.config_dict['my_attr'][key] = value
Single core
300k RPS on multicore?
Andrew Svetlov
@andrew_svetlov
andrew.svetlov@gmail.com
http://asvetlov.github.io/pycon-ru-2018/