Александр Кошелев: Препарирование работы...
-
Upload
it-people -
Category
Technology
-
view
849 -
download
1
description
Transcript of Александр Кошелев: Препарирование работы...
![Page 1: Александр Кошелев: Препарирование работы асинхронного кода](https://reader033.fdocuments.us/reader033/viewer/2022052507/557f77a8d8b42a55278b4672/html5/thumbnails/1.jpg)
ПРЕПАРИРОВАНИЕ РАБОТЫАСИНХРОННОГО КОДА
Александр Кошелев, ЯндексPyCon Россия, 2013
![Page 2: Александр Кошелев: Препарирование работы асинхронного кода](https://reader033.fdocuments.us/reader033/viewer/2022052507/557f77a8d8b42a55278b4672/html5/thumbnails/2.jpg)
ЗАЧЕМAsynchronous is a new coolЭффективностьМного io-boundМало cpu-bound
Высокие нагрузкиМного клиентов
![Page 3: Александр Кошелев: Препарирование работы асинхронного кода](https://reader033.fdocuments.us/reader033/viewer/2022052507/557f77a8d8b42a55278b4672/html5/thumbnails/3.jpg)
КАКИнструменты на выбор
TwistedTornadoAsyncoreGevent...Node.js
Можно написать своё
![Page 4: Александр Кошелев: Препарирование работы асинхронного кода](https://reader033.fdocuments.us/reader033/viewer/2022052507/557f77a8d8b42a55278b4672/html5/thumbnails/4.jpg)
EVENT LOOPОпрос сокетовВызов хендлеров
Обработка таймаутовВызов колбеков
![Page 5: Александр Кошелев: Препарирование работы асинхронного кода](https://reader033.fdocuments.us/reader033/viewer/2022052507/557f77a8d8b42a55278b4672/html5/thumbnails/5.jpg)
EVENT LOOPwhile running: do_handle_sockets()
do_handle_timeouts()
do_handle_callbacks()
![Page 6: Александр Кошелев: Препарирование работы асинхронного кода](https://reader033.fdocuments.us/reader033/viewer/2022052507/557f77a8d8b42a55278b4672/html5/thumbnails/6.jpg)
ЭТО ЗНАЧИТВсе запросы обрабатываются в одном процессеОбработка одного запроса влияет на другиеТребуется изоляция контекста каждого запроса
![Page 7: Александр Кошелев: Препарирование работы асинхронного кода](https://reader033.fdocuments.us/reader033/viewer/2022052507/557f77a8d8b42a55278b4672/html5/thumbnails/7.jpg)
ГЛАВНЫЕ ПРАВИЛАНельзя блокироватьсяРазбивка на короткие этапыОбязательно io-bound
![Page 8: Александр Кошелев: Препарирование работы асинхронного кода](https://reader033.fdocuments.us/reader033/viewer/2022052507/557f77a8d8b42a55278b4672/html5/thumbnails/8.jpg)
ЭКСПЕРИМЕНТTornadocpu-boundОснован на реальной задаче
![Page 9: Александр Кошелев: Препарирование работы асинхронного кода](https://reader033.fdocuments.us/reader033/viewer/2022052507/557f77a8d8b42a55278b4672/html5/thumbnails/9.jpg)
ЭКСПЕРИМЕНТТЕСТОВОЕ ПРИЛОЖЕНИЕ
Принять запросПараллельно опросить бекэнды — принципиальноОбработать данныеОтдать ответ
![Page 10: Александр Кошелев: Препарирование работы асинхронного кода](https://reader033.fdocuments.us/reader033/viewer/2022052507/557f77a8d8b42a55278b4672/html5/thumbnails/10.jpg)
ЭКСПЕРИМЕНТТЕСТОВОЕ ПРИЛОЖЕНИЕ
![Page 11: Александр Кошелев: Препарирование работы асинхронного кода](https://reader033.fdocuments.us/reader033/viewer/2022052507/557f77a8d8b42a55278b4672/html5/thumbnails/11.jpg)
ЭКСПЕРИМЕНТХЕНДЛЕР
class AppHandler(object): @gen.engine def process(self, callback): yield gen.Task(self.do_io) self.do_cpu()
results = yield [gen.Task(self.do_branch), gen.Task(self.do_branch)] self.do_cpu()
yield gen.Task(self.do_io) self.do_cpu()
callback('ok')
![Page 12: Александр Кошелев: Препарирование работы асинхронного кода](https://reader033.fdocuments.us/reader033/viewer/2022052507/557f77a8d8b42a55278b4672/html5/thumbnails/12.jpg)
ЭКСПЕРИМЕНТХЕНДЛЕР
class AppHandler(object): # ...
def do_cpu(self, cycles=1000000): for _ in xrange(cycles): pass
@gen.engine def do_io(self, callback): yield gen.Task(self.http_client.fetch, 'http://localhost:5001/')
callback(None)
@gen.engine def do_branch(self, callback): yield [gen.Task(self.do_io) for _ in range(5)] self.do_cpu()
callback(None)
![Page 13: Александр Кошелев: Препарирование работы асинхронного кода](https://reader033.fdocuments.us/reader033/viewer/2022052507/557f77a8d8b42a55278b4672/html5/thumbnails/13.jpg)
ЭКСПЕРИМЕНТПРИЛОЖЕНИЕ
from tornado import web
from handler import AppHandler
class RootHandler(web.RequestHandler): @web.asynchronous def get(self): handler = AppHandler()
handler.process(self.return_response)
def return_response(self, response): self.finish(response)
application = web.Application([ (r'/', RootHandler),])
![Page 14: Александр Кошелев: Препарирование работы асинхронного кода](https://reader033.fdocuments.us/reader033/viewer/2022052507/557f77a8d8b42a55278b4672/html5/thumbnails/14.jpg)
1 ПАРАЛЛЕЛЬНЫЙ ЗАПРОС
![Page 15: Александр Кошелев: Препарирование работы асинхронного кода](https://reader033.fdocuments.us/reader033/viewer/2022052507/557f77a8d8b42a55278b4672/html5/thumbnails/15.jpg)
1 ПАРАЛЛЕЛЬНЫЙ ЗАПРОС
![Page 16: Александр Кошелев: Препарирование работы асинхронного кода](https://reader033.fdocuments.us/reader033/viewer/2022052507/557f77a8d8b42a55278b4672/html5/thumbnails/16.jpg)
N ПАРАЛЛЕЛЬНЫХ ЗАПРОСОВ
![Page 17: Александр Кошелев: Препарирование работы асинхронного кода](https://reader033.fdocuments.us/reader033/viewer/2022052507/557f77a8d8b42a55278b4672/html5/thumbnails/17.jpg)
3 ПАРАЛЛЕЛЬНЫХ ЗАПРОСА
![Page 18: Александр Кошелев: Препарирование работы асинхронного кода](https://reader033.fdocuments.us/reader033/viewer/2022052507/557f77a8d8b42a55278b4672/html5/thumbnails/18.jpg)
ВЫВОДЫЗапросы мешают друг другу из-за cpu-bound задачРастет время ответаЖадность
![Page 19: Александр Кошелев: Препарирование работы асинхронного кода](https://reader033.fdocuments.us/reader033/viewer/2022052507/557f77a8d8b42a55278b4672/html5/thumbnails/19.jpg)
WORKAROUNDFLASK + TORNADO IOLOOP
Синхронный воркерНе жадныйНо нужно несколько процессов
Event loop внутриПараллельный опрос бекэндов
![Page 20: Александр Кошелев: Препарирование работы асинхронного кода](https://reader033.fdocuments.us/reader033/viewer/2022052507/557f77a8d8b42a55278b4672/html5/thumbnails/20.jpg)
FLASK + TORNADO IOLOOPРЕАКТОР
def do(handler, args=(), kwargs={}): io_loop = tornado.ioloop.IOLoop.instance()
result = [None]
def callback(result_): result[0] = result_
io_loop.stop()
kwargs['callback'] = callback handler(*args, **kwargs)
io_loop.start()
return result[0]
![Page 21: Александр Кошелев: Препарирование работы асинхронного кода](https://reader033.fdocuments.us/reader033/viewer/2022052507/557f77a8d8b42a55278b4672/html5/thumbnails/21.jpg)
FLASK + TORNADO IOLOOPПРИЛОЖЕНИЕ
from flask import Flask
import handler, reactor
application = Flask(__name__)
@application.route('/')def root(): hndl = handler.AppHandler()
response = reactor.do(hndl.process)
return response
![Page 22: Александр Кошелев: Препарирование работы асинхронного кода](https://reader033.fdocuments.us/reader033/viewer/2022052507/557f77a8d8b42a55278b4672/html5/thumbnails/22.jpg)
1 ПАРАЛЛЕЛЬНЫЙ ЗАПРОС
![Page 23: Александр Кошелев: Препарирование работы асинхронного кода](https://reader033.fdocuments.us/reader033/viewer/2022052507/557f77a8d8b42a55278b4672/html5/thumbnails/23.jpg)
1 ПАРАЛЛЕЛЬНЫЙ ЗАПРОС
![Page 24: Александр Кошелев: Препарирование работы асинхронного кода](https://reader033.fdocuments.us/reader033/viewer/2022052507/557f77a8d8b42a55278b4672/html5/thumbnails/24.jpg)
N ПАРАЛЛЕЛЬНЫХ ЗАПРОСОВ
![Page 25: Александр Кошелев: Препарирование работы асинхронного кода](https://reader033.fdocuments.us/reader033/viewer/2022052507/557f77a8d8b42a55278b4672/html5/thumbnails/25.jpg)
3 ПАРАЛЛЕЛЬНЫХ ЗАПРОСА
![Page 26: Александр Кошелев: Препарирование работы асинхронного кода](https://reader033.fdocuments.us/reader033/viewer/2022052507/557f77a8d8b42a55278b4672/html5/thumbnails/26.jpg)
ИТОГИВремя не зависит от числа параллельных запросовБолее предсказуемое поведение
![Page 27: Александр Кошелев: Препарирование работы асинхронного кода](https://reader033.fdocuments.us/reader033/viewer/2022052507/557f77a8d8b42a55278b4672/html5/thumbnails/27.jpg)
ВЫВОДЫБаланс cpu-bound/io-boundВсё зависит от задачи
![Page 28: Александр Кошелев: Препарирование работы асинхронного кода](https://reader033.fdocuments.us/reader033/viewer/2022052507/557f77a8d8b42a55278b4672/html5/thumbnails/28.jpg)
ВОПРОСЫ?Спасибо
Александр Кошелев, Яндекс