260 likes | 271 Views
Trilha – Python. Jeff Andrade. Developer - CI&T. Jeff Andrade. LinkedIn. Github. Como fazer mais de uma coisa ao mesmo tempo com Python?. Multiprocessing. Multithreading. Asyncio. Como funciona?.
E N D
Trilha – Python Jeff Andrade Developer - CI&T
Jeff Andrade LinkedIn Github
Como fazer mais de uma coisa ao mesmo tempo com Python? Multiprocessing Multithreading Asyncio
Como funciona? Multiprocessing: Gerenciado pelo sistema operacional. A concorrência é com base na quantidade de núcleos do processador (muti-core). Multithreading: Gerenciado pelo sistema operacional. No caso do Cpython, é executado em um único núcleo do processador (não suporta multi-core). Async não depende do sistema operacional. Utiliza um processo, uma thread. O gerenciamento se dá através de um scheduler chamado de Event Loop.
Escalabilidade Multiprocessing: 1 → Quantidade de processadores (núcleos) Multithreading: Dezenas, centenas. Concorrência através do tempo de processamento. Async: Milhares → Milhões ?
Requests por segundo Fonte: https://blog.startmatter.com/
Desafio de Xadrez - Miguel Grinberg Cenário 2 Cenário 1 Desafiante x Jogador 1, 2 e 3 Desafiante x Jogador 1 6 minutos Desafiante x Jogador 2 Desafiante x Jogador 3 15 minutos
Generators Python 3 Python 3.5+ import asyncio loop = asyncio.get_event_loop() @asyncio.coroutine def hello(word): print('hello {}'.format(word) @asyncio.coroutine def main(): yeld from hello(‘world’) if __name__ == ‘__main__’: asyncio.run_until_complete(main()) import asyncio async def say_hello(word): print(f’hello {word}’) async def main(): await say_hello(“world”) asyncio.run(main())
import time def hold(sec): print(f'Running for {sec} seconds') return time.sleep(sec) def main(): _start = time.time() hold(3) print(f"Execution time: { time.time() - _start }") if __name__ == '__main__': main()
import time from multiprocessing import Process def hold(sec): print(f'Running for {sec} seconds') return time.sleep(sec) def main(): _start = time.time() times = [2, 3, 4] processes = [] for seconds in times: process = Process(target=hold, args=(seconds,)) processes.append(process) for process in processes: process.start() for process in processes: process.join() print(f"Execution time: { time.time() - _start }") if __name__ == '__main__':
import asyncio import sys import time import aiohttp import async_timeout async def hold(sec): print(f'Running for {sec} seconds') await asyncio.sleep(sec) async def main(): await hold if __name__ == '__main__': _start = time.time() loop = asyncio.get_event_loop() loop.run_until_complete(main) print(f"Execution time: { time.time() - _start }") loop.close()
import asyncio import sys import time import aiohttp import async_timeout async def hold(sec): print(f'Running for {sec} seconds') await asyncio.sleep(sec) async def main(): times = [2, 3, 4] tasks = [] for seconds in times: task = asyncio.ensure_future(hold(seconds)) tasks.append(task) await asyncio.gather(*tasks) if __name__ == '__main__': _start = time.time() loop = asyncio.get_event_loop() future = asyncio.ensure_future(main()) loop.run_until_complete(future) print(f"Execution time: { time.time() - _start }") loop.close()
Serviços real-time Long-polling Websockets Server-sent Events
Docker – Python 3.7 + gunicorn FROM python:3.7 ENV PYTHONUNBUFFERED 1 ENV C_FORCE_ROOT true WORKDIR /src ADD ./src /src RUN pip install --upgrade pip RUN pip install -r requirements.txt CMD gunicorn server:factory --bind 0.0.0.0:8000 --worker-class aiohttp.GunicornWebWorker
import asyncio import json from aiohttp.web import Application, Response from aiohttp_sse import sse_response import aiohttp_cors import sockjs rooms = {} users = {} async def factory(): loop = asyncio.get_event_loop() app = Application(loop=loop) cors = aiohttp_cors.setup(app, defaults={ "*": aiohttp_cors.ResourceOptions( allow_credentials=True, expose_headers="*", allow_headers="*", ) }) sockjs.add_endpoint(app, ws_poll, name='ws', prefix='/ws/') return app
async def ws_poll(msg, session): if msg.type == sockjs.MSG_OPEN: print('new user') print(session.id) elif msg.type == sockjs.MSG_MESSAGE: data = json.loads(msg.data) print(data) elif msg.type == sockjs.MSG_CLOSED: print(‘user left’) else: print(‘mds, nunca deveria ter caído nesse else...’)
<chessboard @onMove="updateBoard" :fen="currentGame"></chessboard>let self = this if(this.socket) { this.socket.send(JSON.stringify({'type': 'new_move', 'player': this.player.id, 'room': this.room, 'fen': currentGame.fen})) } if msg.type == sockjs.MSG_MESSAGE: data = json.loads(msg.data) if data['type'] == 'new_move': room_name = data['room'] for user in rooms[room_name]['sessions']: user.send(json.dumps({'type': 'update', 'fen': data['fen']})) self.socket.onmessage = function(e) { let msg_obj = JSON.parse(e.data) if(msg_obj.type == 'update'){ console.log('updating game') self.currentGame = msg_obj.fen } }
LinkedIn Github MUITO OBRIGADO!