Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Programação Assíncrona com Asyncio

Programação Assíncrona com Asyncio

Palestra ministrada no PythonDay Campina Grande 2017

13991d197c3eb0f71b802337d5eb2719?s=128

Allisson Azevedo

March 25, 2017
Tweet

Transcript

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

    1
  2. ALLISSON AZEVEDO allissonazevedo.com youtube.com/user/allissonazevedo github.com/allisson twitter.com/allisson linkedin.com/in/allisson/ allisson.github.io/slides/ allisson@gmail.com 2

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

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

    paralelismo 4
  5. 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
  6. PROBLEMAS COM PROGRAMAÇÃO SÍNCRONA Uma requisição http por vez 6

  7. 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
  8. PROBLEMAS COM THREADS Consumo de recursos Global Interpreter Lock (GIL)

    8
  9. 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
  10. PROBLEMAS COM PROCESS Consumo de recursos 10

  11. 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
  12. PROBLEMAS COM CONCURRENT.FUTURES ThreadPoolExecutor - usa threads ProcessPoolExecutor - usa

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

  14. ASYNCIO Python 3.4+ Tulip PEP-3156 14

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

    = asyncio.get_event_loop() loop.run_until_complete(hello_world()) 15
  16. 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
  17. 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
  18. AIO LIBS https://github.com/aio-libs https://github.com/python/asyncio/wiki/ThirdParty 18

  19. 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
  20. 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
  21. 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
  22. 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
  23. 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
  24. 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
  25. 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
  26. 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
  27. PERGUNTAS? 27

  28. OBRIGADO! 28