pen4education Seu Primeiro Loop com AsyncIO Carlos Maniero Desenvolvedor Python na Loja Integrada
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