programação assíncrona com asyncio

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

Upload: allisson-azevedo

Post on 06-Apr-2017

78 views

Category:

Technology


2 download

TRANSCRIPT

PROGRAMAÇÃO ASSÍNCRONA COMASYNCIO

PythonDay Campina Grande 2017

Allisson Azevedo

1

ALLISSON AZEVEDOallissonazevedo.com

youtube.com/user/allissonazevedo

github.com/allisson

twitter.com/allisson

linkedin.com/in/allisson/

allisson.github.io/slides/

[email protected]

2

THE C10K PROBLEMComo lidar com 10k conexões simultâneas

http://www.kegel.com/c10k.html

3

CONCORRÊNCIA

Asynchronous I/O

O exemplo do garçom

Não confundir com paralelismo

4

PROGRAMAÇÃO SÍNCRONAimport 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_TOKEN}).json() 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

PROBLEMAS COM PROGRAMAÇÃOSÍNCRONA

Uma requisição http por vez

6

CONCORRÊNCIA USANDO THREADSimport 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

PROBLEMAS COM THREADS

Consumo de recursos

Global Interpreter Lock (GIL)

8

CONCORRÊNCIA USANDO PROCESSimport 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

PROBLEMAS COM PROCESSConsumo de recursos

10

CONCORRÊNCIA USANDOCONCURRENT.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_TOKEN}).json() repo_info = { 'name': response['name'], 'full_name': response['full_name'], 'stargazers_count': response['stargazers_count'] } print(repo_info)

11

PROBLEMAS COMCONCURRENT.FUTURES

ThreadPoolExecutor - usa threads

ProcessPoolExecutor - usa process

12

HELLO WORLDimport asyncio

async def hello_world(): print('Hello World!')

loop = asyncio.get_event_loop() loop.run_until_complete(hello_world())

15

HELLO WORLD COM TASKSimport 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

CONCORRÊNCIA USANDO ASYNCIOimport 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': ACCESS_TOKEN}) 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

AIO LIBShttps://github.com/aio-libs

https://github.com/python/asyncio/wiki/ThirdParty

18

PACOimport 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': ACCESS_TOKEN}) 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

AIOHTTPfrom 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

SANICfrom 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

AIOREDISimport asyncio import aioredis

loop = asyncio.get_event_loop()

async def main(): redis = await aioredis.create_redis(('localhost', 6379), loop=loop) 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

AIOMCACHEimport 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

AIOPGimport asyncio import aiopg from speakers import SPEAKERS

dsn = 'dbname=pythonday user=pythonday password=pythonday host=127.0.0.1'

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

AIOPG SQLALCHEMYimport 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

PYTEST-ASYNCIOimport 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': ACCESS_TOKEN}) response_data = await response.json() return { 'name': response_data['name'], 'full_name': response_data['full_name'], 'stargazers_count': response_data['stargazers_count' }

26

PERGUNTAS?

27

OBRIGADO!

28