pen4education
Seu Primeiro Loop com AsyncIOCarlos Maniero
Desenvolvedor Python na Loja Integrada
pen4education
Não tenha medo
pen4education
Motivacional
“É necessário a disciplina de um super humano para escrever código legível baseado em
callbacks, se você não acredita em mim, olhe qualquer pedaço de código javascript.”
pen4education
Motivacional
“É necessário a disciplina de um super humano para escrever código legível baseado em
callbacks, se você não acredita em mim, olhe qualquer pedaço de código javascript.”
Guido Van Rossum
pen4education
Motivacional
https://www.python.org/~guido/
pen4education
Polêmica
“Threads em Python são excelentes em fazer nada.”
David Beazleyhttp://www.dabeaz.com/
pen4education
Hello World
import asyncio
async def hello_world(): print("Hello World!")
loop = asyncio.get_event_loop()loop.run_until_complete(hello_world())loop.close()
Python 3.5
pen4education
Hello World
import asyncio
@asyncio.coroutinedef hello_world(): print("Hello World!")
loop = asyncio.get_event_loop()loop.run_until_complete(hello_world())loop.close()
Python 3.4
pen4education
Py 3.4 vs Py 3.5
Python 3.4 Python 3.5
async def hello_world():@asyncio.coroutinedef hello_world():
await x()yield from x()
pen4education
Event Loop
O Event Loop é o dispositivo central de execução.
● Registra, executar e cancela tarefas● Cria servidores e clients para vários tipos de
comunicação (ex: sockets)● Delega processos pesados a um executor. (ex:
ThreadPoolExecutor)
pen4education
Coroutine
Coroutine utiliza do statement yield do Python para controlar a execução do código de uma função. Sendo possível bloquear, continuar e realizar a comunicação sem a necessidade de criação de funções de callback.
pen4education
Coroutine
def media():n = 1total = yieldwhile True:
total += (yield total / n) n += 1
coro = media()next(coro)print(coro.send(10))>>> 10.0print(coro.send(20))>>> 15.0
pen4education
Coroutine
def media():n = 1total = yieldwhile True:
total += (yield total / n) n += 1
coro = media()next(coro)print(coro.send(10))>>> 10.0print(coro.send(20))>>> 15.0
pen4education
Coroutine
def media():n = 1total = yieldwhile True:
total += (yield total / n) n += 1
coro = media()next(coro)print(coro.send(10))>>> 10.0print(coro.send(20))>>> 15.0
n total
1 None
pen4education
Coroutine
def media():n = 1total = yieldwhile True:
total += (yield total / n) n += 1
coro = media()next(coro)print(coro.send(10))>>> 10.0print(coro.send(20))>>> 15.0
n total
1 10
pen4education
Coroutine
def media():n = 1total = yieldwhile True:
total += (yield total / n) n += 1
coro = media()next(coro)print(coro.send(10))>>> 10.0print(coro.send(20))>>> 15.0
n total
2 30
pen4education
Coroutine
def media():n = 1total = yieldwhile True:
total += (yield total / n) n += 1
coro = media()next(coro)print(coro.send(10))>>> 10.0print(coro.send(20))>>> 15.0
n total
2 30
pen4education
Coroutine
def media():n = 1total = yieldwhile True:
total += (yield total / n) n += 1
coro = media()next(coro)print(coro.send(10))>>> 10.0print(coro.send(20))>>> 15.0
n total
2 30
pen4education
Task/Future
● Responsável pelo controle de execução de uma corroutine.
● Contém importantes métodos como done(), result() e cancel().
● Uma Task só é gerada pelo asyncio, utilizando o asyncio.ensure_future() ou o loop.create_task().
pen4education
import asyncio
async def loading():i = 1while True:
print('Loading ' + '.' * i) await asyncio.sleep(0.5) i += 1
async def run_very_long_task():await asyncio.sleep(3)return 42
async def supervisor():loading_task = asyncio.ensure_future(loading()) # Cria taskcontent = await run_very_long_task() # Espera por retornoloading_task.cancel() # Cancela execução da taskprint('The result is {}'.format(content))
loop = asyncio.get_event_loop()loop.run_until_complete(supervisor())loop.close()
Task/Future
pen4education
import asyncio
async def loading():i = 1while True:
print('Loading ' + '.' * i) await asyncio.sleep(0.5) i += 1
async def run_very_long_task():await asyncio.sleep(3)return 42
async def supervisor():loading_task = asyncio.ensure_future(loading()) # Cria taskcontent = await run_very_long_task() # Espera por retornoloading_task.cancel() # Cancela execução da taskprint('The result is {}'.format(content))
loop = asyncio.get_event_loop()loop.run_until_complete(supervisor())loop.close()
Task/Future
Loading .Loading ..Loading ...Loading ....Loading .....Loading ......The result is 42
pen4education
import asyncio
async def loading():i = 1while True:
print('Loading ' + '.' * i) await asyncio.sleep(0.5) i += 1
async def run_very_long_task():await asyncio.sleep(3)return 42
async def supervisor():loading_task = asyncio.ensure_future(loading()) content = await run_very_long_task()loading_task.cancel()print('The result is {}'.format(content))
loop = asyncio.get_event_loop()loop.run_until_complete(supervisor())loop.close()
pen4education
import asyncio
async def loading():i = 1while True:
print('Loading ' + '.' * i) await asyncio.sleep(0.5) i += 1
async def run_very_long_task():await asyncio.sleep(3)return 42
async def supervisor():loading_task = asyncio.ensure_future(loading()) content = await run_very_long_task()loading_task.cancel()print('The result is {}'.format(content))
loop = asyncio.get_event_loop()loop.run_until_complete(supervisor())loop.close()
pen4education
import asyncio
async def loading():i = 1while True:
print('Loading ' + '.' * i) await asyncio.sleep(0.5) i += 1
async def run_very_long_task():await asyncio.sleep(3)return 42
async def supervisor():loading_task = asyncio.ensure_future(loading()) content = await run_very_long_task()loading_task.cancel()print('The result is {}'.format(content))
loop = asyncio.get_event_loop()loop.run_until_complete(supervisor())loop.close()
pen4education
import asyncioimport time
def slow_function(): time.sleep(3) return 42
async def test1(): slow_function() print('Finish test1')
async def test2(): for i in range(0, 10): print(i) await asyncio.sleep(0.5) print('Finish test2')
loop = asyncio.get_event_loop()loop.run_until_complete(asyncio.wait([
test1(),test2()
]))
Bloqueio do Loop
Finish test10123456789Finish test2
pen4education
import asyncioimport time
def slow_function(): time.sleep(3) return 42
async def test1(): await loop.run_in_executor(None, slow_function) print('Finish test1')
async def test2(): for i in range(0, 10): print(i) await asyncio.sleep(0.5) print('Finish test2')
loop = asyncio.get_event_loop()loop.run_until_complete(asyncio.wait([
test1(),test2()
]))
Bloqueio do Loop
012345Finish test16789Finish test2
pen4education
O que ver a seguir?
● ThreadPoolExecutor● aioHTTP