Slide 1

Slide 1 text

PROGRAMAÇÃO ASSÍNCRONA COM ASYNCIO PythonDay Campina Grande 2017 Allisson Azevedo 1

Slide 2

Slide 2 text

ALLISSON AZEVEDO allissonazevedo.com youtube.com/user/allissonazevedo github.com/allisson twitter.com/allisson linkedin.com/in/allisson/ allisson.github.io/slides/ [email protected] 2

Slide 3

Slide 3 text

THE C10K PROBLEM Como lidar com 10k conexões simultâneas http://www.kegel.com/c10k.html 3

Slide 4

Slide 4 text

CONCORRÊNCIA Asynchronous I/O O exemplo do garçom Não confundir com paralelismo 4

Slide 5

Slide 5 text

PROGRAMAÇÃO SÍNCRONA import time import requests from github import REPOS, ACCESS_TOKEN start = time.time() for repo_url in REPOS: response = requests.get(repo_url, params={'access_token': ACCESS repo_info = { 'name': response['name'], 'full_name': response['full_name'], 'stargazers_count': response['stargazers_count'] } print(repo_info) end = time.time() print('Tempo de execução={:.2f} segundos'.format(end - start)) 5

Slide 6

Slide 6 text

PROBLEMAS COM PROGRAMAÇÃO SÍNCRONA Uma requisição http por vez 6

Slide 7

Slide 7 text

CONCORRÊNCIA USANDO THREADS import time import threading import queue import requests from github import REPOS, ACCESS_TOKEN def grab_data_from_queue(): while not q.empty(): repo_url = q.get() response = requests.get(repo_url, params={'access_token' repo_info = { 'name': response['name'], 'full_name': response['full_name'], 'stargazers_count': response['stargazers_count'] } 7

Slide 8

Slide 8 text

PROBLEMAS COM THREADS Consumo de recursos Global Interpreter Lock (GIL) 8

Slide 9

Slide 9 text

CONCORRÊNCIA USANDO PROCESS import time import multiprocessing import requests from github import REPOS, ACCESS_TOKEN def grab_data_from_queue(): while not q.empty(): repo_url = q.get() response = requests.get(repo_url, params={'access_token' repo_info = { 'name': response['name'], 'full_name': response['full_name'], 'stargazers_count': response['stargazers_count'] } print(repo_info) 9

Slide 10

Slide 10 text

PROBLEMAS COM PROCESS Consumo de recursos 10

Slide 11

Slide 11 text

CONCORRÊNCIA USANDO CONCURRENT.FUTURES import time from concurrent import futures import requests from github import REPOS, ACCESS_TOKEN def get_repo_info(repo_url): response = requests.get(repo_url, params={'access_token': ACCESS repo_info = { 'name': response['name'], 'full_name': response['full_name'], 'stargazers_count': response['stargazers_count'] } print(repo_info) 11

Slide 12

Slide 12 text

PROBLEMAS COM CONCURRENT.FUTURES ThreadPoolExecutor - usa threads ProcessPoolExecutor - usa process 12

Slide 13

Slide 13 text

ASYNCHRONOUS I/O COM PYTHON Twisted Tornado Eventlet Gevent Asyncio 13

Slide 14

Slide 14 text

ASYNCIO Python 3.4+ Tulip PEP-3156 14

Slide 15

Slide 15 text

HELLO WORLD import asyncio async def hello_world(): print('Hello World!') loop = asyncio.get_event_loop() loop.run_until_complete(hello_world()) 15

Slide 16

Slide 16 text

HELLO WORLD COM TASKS import asyncio async def hello_world(name): print('Hello World, {}!'.format(name)) loop = asyncio.get_event_loop() tasks = [] for name in ('fulano', 'cicrano', 'beltrano'): task = asyncio.ensure_future(hello_world(name)) tasks.append(task) loop.run_until_complete(asyncio.wait(tasks)) 16

Slide 17

Slide 17 text

CONCORRÊNCIA USANDO ASYNCIO import time import asyncio import aiohttp from github import REPOS, ACCESS_TOKEN async def get_repo_info(repo_url): async with aiohttp.ClientSession() as session: async with session.get(repo_url, params={'access_token': ACC response_data = await response.json() repo_info = { 'name': response_data['name'], 'full_name': response_data['full_name'], 'stargazers_count': response_data['stargazers_count' } print(repo_info) 17

Slide 18

Slide 18 text

AIO LIBS https://github.com/aio-libs https://github.com/python/asyncio/wiki/ThirdParty 18

Slide 19

Slide 19 text

PACO import time import paco import aiohttp from github import REPOS, ACCESS_TOKEN async def get_repo_info(repo_url): async with aiohttp.ClientSession() as session: async with session.get(repo_url, params={'access_token': ACC response_data = await response.json() repo_info = { 'name': response_data['name'], 'full_name': response_data['full_name'], 'stargazers_count': response_data['stargazers_count' } print(repo_info) 19

Slide 20

Slide 20 text

AIOHTTP from aiohttp import web async def handle(request): return web.json_response({'message': 'Hello World'}) app = web.Application() app.router.add_get('/', handle) web.run_app(app, host='127.0.0.1', port=8080) 20

Slide 21

Slide 21 text

SANIC from sanic import Sanic from sanic.response import json app = Sanic() @app.route('/') async def test(request): return json({'message': 'Hello World'}) if __name__ == '__main__': app.run(host='127.0.0.1', port=8080) 21

Slide 22

Slide 22 text

AIOREDIS import asyncio import aioredis loop = asyncio.get_event_loop() async def main(): redis = await aioredis.create_redis(('localhost', 6379), loop=lo await redis.set('key', 'hello world') val = await redis.get('key') print(val) redis.close() await redis.wait_closed() loop.run_until_complete(main()) 22

Slide 23

Slide 23 text

AIOMCACHE import asyncio import aiomcache loop = asyncio.get_event_loop() async def main(): mc = aiomcache.Client('127.0.0.1', 11211, loop=loop) await mc.set(b'key', b'hello world') value = await mc.get(b'key') print(value) loop.run_until_complete(main()) 23

Slide 24

Slide 24 text

AIOPG import asyncio import aiopg from speakers import SPEAKERS dsn = 'dbname=pythonday user=pythonday password=pythonday host=127. async def get_pool(): return await aiopg.create_pool(dsn) async def create_table(): pool = await get_pool() async with pool.acquire() as conn: async with conn.cursor() as cur: await cur.execute('DROP TABLE IF EXISTS speakers') 24

Slide 25

Slide 25 text

AIOPG SQLALCHEMY import asyncio from aiopg.sa import create_engine import sqlalchemy as sa from speakers import SPEAKERS metadata = sa.MetaData() speakers_table = sa.Table( 'speakers', metadata, sa.Column('id', sa.Integer, primary_key=True), sa.Column('name', sa.String(255)) ) async def get_engine(): return await create_engine( 25

Slide 26

Slide 26 text

PYTEST-ASYNCIO import pytest import aiohttp from github import REPOS, ACCESS_TOKEN async def get_repo_info(repo_url): async with aiohttp.ClientSession() as session: async with session.get(repo_url, params={'access_token': ACC response_data = await response.json() return { 'name': response_data['name'], 'full_name': response_data['full_name'], 'stargazers_count': response_data['stargazers_count' } 26

Slide 27

Slide 27 text

PERGUNTAS? 27

Slide 28

Slide 28 text

OBRIGADO! 28