Открыть изображение »
asyncio. Самая благостная фича Python со времен 3.0
24 ноября 2016 :: 48 комментариев :: 3361 просмотр :: 1065 слов
Форкающиеся и тредящиеся шарманки пускай подыхают вместе с богохульными Apache и персональными веб-сайтами, а современный блаженный бекенд должен быть неблокирующим. По крайней мере та его часть, которая принимает запросы пользователей. Для этого у кодобояр на боголюбимом Python с давних пор был tornado, который лихо имитировал асинхронность оборачивая ваш код в генераторы и заруливая это в свой бесконечный цикл aka ивентлуп из семи сами знаете чего. Идея так-то странная, но работала, и торнада стала первым веб-сервером на питоне, который выдерживал проблему 10К соединений.
В последнее время нормальные ребята бросились писать на Go, и ликовать от компилируемости и няшного маскота-грызуна. Я уже почти было сдался и готов был привыкнуть к карательному способу возврата ошибок в Go, но нулевой тулинг и отсутствие хоть каких-то библиотек для взрослых не давало мне покоя. Пусть вимеры sed'ом рефакторят. Ставь Atom говорят, заебись редактор, всего 16 Гб памяти жрет и не открывает файлы больше 5 Мб, зато синтаксис подсвечивает, инновация. Инженеры переднего конца наговнякали на джаваскрипте, не иначе.
[скрыть все] [развернуть все]  11 комментариев
Потом нам пообещали Python 3.5 с asyncio в стандарте. Предвкушая этот релиз, я ходил по «уютным квартирникам доброжелательного Go-коммьюнити», где вежливо интересовался: уважаемые, я питонист, но очень хочу в Go. Правильно я понимаю, что из новых для меня плюсов остается только скорость языка, которая в реальной жизни редко является проблемой, так как большую часть времени программа висит в ожидании I/O? Дурак чтоле, горутины же! — отвечали мне в один голос. Я говорю ну вот же, в питоне asyncio, ивентлуп нативный, экстеншенами на С (которых у вас нет) если надо ускоряется в космос, в чем ваши преимущества? Но слово «Python» видимо является rage-триггером для коммьюнити Go, так как в ответ я был лишь обласкан каким-то кукареканьем про «оно же не в стандарте», «у нас было раньше» и «не надо разжигать тут холивар». Ладно. Нервые такие. Наверное из-за err != nil.
Так как на tornado я пишу большинство проектов последние года 4, asyncio я ждал как явление христа. Но только с 3.5 из-за конструкций async/await. Yield'ами обмазаться я и в tornado могу. Если вы пишете на питоне и всё еще не используете async/await — бегом открывать дивный новый мир. Конечно если вы не django-программист, тогда для вас по прежнему единственное развлечение — переписывать половину проекта из-за «небольших несовместимостей» при обновлении с 1.10 на 1.11.
Первое что бросается в глаза в async/await-коде — выпиливание скобочек. Больше никаких for item in (yield something), теперь async for item in something — ну булочка, а не синтаксис. Количество скобочек в проекте сократилось втрое. Да и суммарное количество говна поубавилось, все те костыли тщательно продуманные архитектурные решения, что я тщательно скопил за годы под tornado, остались только в хистори гитхаба. Я даже удалил папочку utils, вы вообще видели такое?!
Бесшовный переход с tornado на asyncio выглядит так: подменяете стандартный eventloop, переходите на aio-либы (для БД, амазона и.т.д), в конце избавляетесь и от самой торнады, заменяя ее aiohttp или чем-то более быстрым (но менее удобным). Все шаги, кроме последнего, при правильной организации проекта не требуют крупных изменений. А на aiohttp вы уже сами всё за вечер переколбасите под эйфорией от процесса.
И вот погружаясь в мир aio-libs становится хорошо и тепло. Наконец-то это единый стандарт, больше никаких «специальных решений» под конкретный фреймворк, никаких tornado-redis — теперь aioredis, никаких странных momoko — теперь aiopg, никаких AsyncHTTPRequest — теперь aiohttp. Тенденция благостна. Все вместе, а не херачат наколеночные костыли под свой ивентлуп.
 +

Да они даже аналог моего уютного GodMode2 сейчас вон пытаются. Наступая на все те же грабли, что и я в первой версии, так мило.
 +
Казалось бы мелочь, заменили одни строчки в requirements.txt на другие, расстроились, что быстрее всего в 8 раз, а не в 16 (© @themylogin). Но нет. aioredis наконец-то рабочая обертка, а не та, где у автора на гитхабе написано «не используйте». Каких-то либ просто никогда не было: для общения с AWS приходилось колхозить обертки над их REST API, а теперь есть aiobotocore. Такой удобный, что я запилил им такой крутой pull-request, что они теперь зовут меня в мейнтейнеры, чем я неприменно должен был похвалиться.
Были штуки, которые раньше сделать было ну почти невозможно. Например очень хотелось, чтобы через стандартный logging выводились ID юзеров, к которым относится данный запрос. Как вы понимаете в асинхронном коде это хитровыебанная задачка, так как нужно всегда знать текущий контекст. Отсюда растут ноги у любви asyncio'шников к конструкции with, в большинстве случаев лишней, чему удивлялся недавно DieGelassenheit. А теперь это решается простым aiolocals, который работает потому что в asyncio можно получать и писать прям в объект current task, который отвечает за конкретный запрос. И больше никаких пробросов контекста в callback, чтобы «логи не потерялись».
Кстати вот это «хранение переменных в чужих объектах» — новый странный паттерн, который активно используют в aio-либах, тот же aiohttp прям так и говорит — херачьте всё в request. На деле удобно, но опасненько в руках говнокодеров. Придется за ними следить, чтобы не устраивали себе в них уютный globals.
 +
Asyncio — киллер-фича Python 3.x. Я так вижу. Раньше ламберсексуалы еще могли вопрошать «зачем мне на 3.x переходить, ради пары новых конструкций чтоле», теперь же буду каждого такого ласкать по густой бороде этим постом. Несмотря на то, что пишу на питоне уже кучу лет и стало хотеться «чего-нибудь новенького» — после aio мысли об измене снова окладываются. Лучше Swift вон поковыряю.
 +
По любимым вами синтетическим уже в своём первом пришествии asyncio обноняет tornado в 5-10 раз, уделывает gevent, и всего в два раза отстает от скоростного Go. И уже есть ускоренные ивентлупы типа uvloop, который использует libuv из node.js, а работает быстрее, чем с родным джаваскриптом. Что на мой взгяд весьма иронично. Подключается одной строкой и вот интерпретируемый язычок внезапно дает писос этим вашим конпеляторам сатанинским.
Но сила языка не в соревнованиях кто быстрее отдаст Hello World на макбуке с ретиной, а в синтаксисе и количестве/качестве библиотек, так как от этого напрямую зависит скорость разработки и цена поддержки, а это уже сурьёзный бизнис просесс. И по этим параметрам на бекенде питону сопоставимы лишь олдскульные гиганты для программистов за 30. Ну или всегда можно наговнякать всё на каком-нить LuaScript, а потом загрустить и уволиться — пусть поищут идиотов, кто это сможет поддерживать, может поймут насколько я незаменим. Мы же художники, нам не задачу решать, а экспериментировать в поисках собственной уникальности! Отхлестал бы всех невидимой рукой рынка.
А если вы ожидали обзора asyncio, то тут его нет. О своём негодовании по поводу сего обязательно расскажите мне в Вастрик.Чате, а так же возвращайтесь в Вастрик.Пынь, там теперь срет не бездушная машина, а я сам.
Еще? Тогда вот
Комментарии
0
.̴̛͖͔̥͔͓͉͋̌́̈́̏ ⸬ 25 ноября 2016, 03:00 ⸬ RU ⸬ Apple лог
#
В общем, простите меня, но этот текст пахнет слепым фанатизмом, одни восторги и насмешки, а из голых фактов упомянут лишь объём готовых библиотек.
0
themylogin ⸬ 25 ноября 2016, 08:52 ⸬ Apple лог
#
К благостным известиям по поводу asyncio добавлю пост Armin Ronacher про его недостатки: http://lucumr.pocoo.org/2016/10/30/i-dont-understand-asyncio/
Честно перечитывал несколько раз, так и не нашёл для себя ничего по существу.
(не заполняйте это поле)