LINUX.ORG.RU

Накидайте интро в экосистему Python

 


3

7

Устроил вот себе такую гимнастику, пиляю тут проектик дома. Язык почитал, концепты понял, с GIL поплевался - успех.

Теперь пытаюсь понять взаимосвязь разных компонентов типичной экосистемы.

Мне нужно - простота, REST, web-sockets, многопоточность работы с этим говном, минимальная отдача статики без шаблонов, бонус - асинхронные клиенты к БД и всяким очередям или шинам сообщений. Нормально было бы еще пользоваться через генераторный интерфейс.

Мне не нужно - ORM, Django, шаблонизация, всякие «тяп-ляп-и-готово» рельсы, куча всякой ненужной «встроенной» поддержки перкомпиляции скриптов и ресурсов и т.д.

Чуть посмотрел Tornado, Twisted, gevent, Flask. Мне в формате запрос-ответ понравилось работать с Flask, с точки зрения API, но ведь это простой синхронный вебсервер, страдающий от GIL веб-фреймворк. Хотелось бы к нему что-то поумнее прикрутить с поддержкой веб-сокетов и многопоточностью

Какой стек порекомендовали бы?

★★★★★

Последнее исправление: vertexua (всего исправлений: 2)

И да, я вот подумал, хм, собственно это web-development

vertexua ★★★★★
() автор топика
Последнее исправление: vertexua (всего исправлений: 1)

а какую собственно поддержку вебсокетов и многопоточности ты ожидаешь от фласка?

val-amart ★★★★★
()
Ответ на: комментарий от val-amart

Я Flask уже поюзал, мне понравилось, но вот в нем есть Flask-Sockets или Flask-SocketIO на основе gevent. Это считается тру? Многопоточности то вроде нет и не будет. Стоит городить что-то посложнее через какие-то Twisted или Tornado?

vertexua ★★★★★
() автор топика
Последнее исправление: vertexua (всего исправлений: 1)
Ответ на: комментарий от vertexua

может я чего-то не понимаю. какой-такой многопоточности ты хочешь?

или по-другому: что ты подразумеваешь под многопоточностью?

или еще по-другому: какую конечную цель ты преследуешь?

val-amart ★★★★★
()
Ответ на: комментарий от val-amart

Задеплою я app. Захочу на нем число Пи считать. Запущу потоков. Python станет колом на GIL. Пример утрирован, за чистую монету можно не принимать.

Да-да, «IO-bound», «не нужно», «сам дурак», но просто хотелось бы узнать как все же можно было через потоки или через процессы организовать работу фреймворка, какого либо. Просто пофоркать и делать вид что это отдельные 4 инстанса приложения в целом? Не говорю что это плохо и не решение, но просто хочу понять как делают обычно в Python-community

vertexua ★★★★★
() автор топика
  • Flask - это не вебсервер. Для него есть много вариантов деплоя. Он вполне может жить внутри гринлета.
  • Большинство питонячего софта деплоятся на сервер как WSGI приложение, а WSGI по своей природе синхронный.
  • Большинство библиотек синхронные.
  • Веб приложения не могут страдать от GIL так как он блокирует только вычисления в потоке, а в большинстве приложений львиная доля времени уходит на ожидание IO. Если приложению нужно что-то считать, это делается в отдельном процессе/процессах. Вопрос архитектуры.
  • Вебсокеты можно реализовать на любом стеке. Отдельный IO Loop + прокся, чтоб рулить.
  • Статику питоном не отдают. Прячь за nginx

Я целиком за асинхронность. И всех агитирую, но тут главное понимать, что кроме слоя твоего приложения есть софт, работу которого надо раскурить.

Для организации асинхронного кода очень советую asyncio из Python 3.4. Удобно, красиво, быстро. Для базы и очереди сообщений(ZeroMQ и PostgreSQL) вчера на хабре Андрей Светлов опубликовал две либы http://habrahabr.ru/post/218423/ я пока не юзал, но обязательно посмотрю.

northicewind
()
Ответ на: комментарий от northicewind

Спасибо.

что кроме слоя твоего приложения есть софт, работу которого надо раскурить.

Вот тут чуть не понял

vertexua ★★★★★
() автор топика
Ответ на: комментарий от vertexua

Для удобного распараллеливания тяжелых расчетов есть модуль concurrent.futures. Только использовать его надо с ProcessPoolExecutor. И все же я бы советовал разделить часть с вычислениями от веб приложения.

northicewind
()
Ответ на: комментарий от vertexua

Я в том смысле, что твое приложение будет зависеть от стороннего софта. Например драйвер базы данных, контейнер приложений(uwsgi например), система логирования(тут вообще тонко, так как дисковое IO нельзя асинхронить), кеширование, хранение сессий и т.д.

Лучше сразу представить себе как и на что ты собираешься деплоить свое приложение, чтоб после долгой разработки все же не нахватать блокировок.

Лучше не смотреть по сети на пузомерки с асинхронными хеллоувордами. В реальной жизни от них толку нет

northicewind
()
Ответ на: комментарий от northicewind

Ок, спасибо, я понял. Нода в принципе жива и здрова по тому же принципу.

vertexua ★★★★★
() автор топика
Ответ на: комментарий от vertexua

да-да, ненужно, io-bound и все прочее.

как и с любым веб приложением, на любом friggin' языке, с использованием любого фреймворка в природе, вычисления надо выделять в отдельный процесс! ни python, ни gil, ни flask совершенно никак не влияют на этот розклад.

конструктивно: в идеале нечто абсолютно независимое, по типу набора процессинг нод на твистеде которые обрабатывают запросы поступающие через MQ. если это просто что-то мелкое для себя и задачи fire-and-forget (без ответа), можно просто multiprocessing и питоновскую очередь. но это не для продакшена.

val-amart ★★★★★
()

«Инструмент под задчу»

Python

многопоточностью

Debasher ★★★★★
()

Многопоточность в веб-сокетах и асинхронность в бд? Да вы батенька знаете толк в извращениях :). Btw, асинхронность на yield'ах во фласке таки есть - http://flask.pocoo.org/docs/patterns/streaming/.

ei-grad ★★★★★
()
Ответ на: комментарий от val-amart

А celery как?

Кстати как я понял, gevent работает на greenlet, который как-то патчит множество системных вызовов. Значит ли это что ожидание ответа от celery или multiprocessing будет неблокирующим? Или я все спутал и смешал в кучу? (собственно о этом и тред)

vertexua ★★★★★
() автор топика
Последнее исправление: vertexua (всего исправлений: 1)
Ответ на: комментарий от val-amart

А что с ней нет так? И что я не так сказал? Просто не понято что неосиливать в mq. И вот я хочу припарковать запрос, чтобы селера минуту поколбасила, на сервере освободить интерпретатор на это время, при ответе продолжить?

vertexua ★★★★★
() автор топика
Ответ на: комментарий от vertexua

И вот я хочу припарковать запрос, чтобы селера минуту поколбасила, на сервере освободить интерпретатор на это время, при ответе продолжить?

я не понял вообще. ты хочешь отправить задание в очередь а потом его забрать через какое-то время тем же тредом?

val-amart ★★★★★
()
Ответ на: комментарий от val-amart

Например да. Не обязательно тем же тредом. Ведь строго говоря тред и сокет клиента не пробиты гвоздями. Часто это тот же тред. Если это нода - то один единственный. Если скала - то какой выделит форк джойн пул

vertexua ★★★★★
() автор топика
Ответ на: комментарий от vertexua

Важно то, чтобы отпустить тред на время работы селеры, он не должен торчать на ожидании блокирующий операции, пусть обрабатывает другие запросы

vertexua ★★★★★
() автор топика
Ответ на: комментарий от vertexua

ну и что из этого нельзя сделать без селеры через обычный mq? незнаю, мне все время кажеться что мы на разных языках говорим — я не понимаю, что ты хочешь и что не получается. возможно, какие аналогии ты пытаешься провести.

тебя волнует гил? узбагойся.

ты хочешь асинхронно работать с внешним ресурсом? используй asyncio, или на крайняк что-то из предшественников — тот же twisted и tornado.

ты хочешь эффективно обрабатывать много подключений по http? используй любой транспортный фреймворк по вкусу, желательно за нормальным uwsgi сервером.

val-amart ★★★★★
()
Ответ на: комментарий от vertexua

конкретно про очереди — да хоть в стандартный Queue пихай свою задачу. главное это как и чем ты ее обработаешь, и как отправишь ответ. очереди асинхронны по определению.

val-amart ★★★★★
()
Ответ на: комментарий от val-amart

тебя волнует гил? узбагойся.

Собственно я могу смириться, но учитывать его в дизайне софта, а просто закрывать глаза - глупо.

vertexua ★★★★★
() автор топика
Ответ на: комментарий от vertexua

я что, угадал, и вся «проблема» это GIL?

а можно полюбопытствовать, какие конкретно неудобства тебе доставляет гил и как ты собрался их обходить, а также почему эти методы «обхода» не являются предпочтительным решением вне зависимости от гила и его ограничений?

val-amart ★★★★★
()
Ответ на: комментарий от val-amart

Я просто спрашиваю две вещи.

1) Что делают пайтонщики когда им на сам фронтенд дают четырехядерный сервак вместо четырех одноядерных? Не парятся или делают много процессов? Я не ругаю GIL, просто спрашиваю что делают.

2) Если использовать gevent/greenlet чтобы пользоваться селерой наиболее природным, с виду, блокирующим способом, то это будет работать?

vertexua ★★★★★
() автор топика
Ответ на: комментарий от vertexua

1) не парятся, это проблемы сисадминов, ичсх есть нормальные удобные способы с ними справиться. с точки зрения программиста, оно просто работает магическим образом.

если надо запускать асинхронные cpu-bound задачи, то во-первых по красаве надо иметь отдельный процесс-считалку и посылать ей задачи через очередь, желательно MQ. а во-вторых если впадлу делать нормально то можно и нужно использовать multiprocessing. преимущества тредов перед процессами на юниксах — вообще спорная тема, а с учетом удобства батареек для взаимодействия с подпроцессом в питоне я вообще в них не вижу смысла.

2) селера — ненужный велосипед, но велосипед заточенный на _асинхронное_ приминение. и ты хочешь синхронно запускать задачи через селеру? это блиин, это хуже чем гланды через жопу. запускай свои задачи синхронно тогда. хочешь блокироваться а-ля в отдельном треде? используй любой из обычных методов: аио, отдельный тред, отдельный процесс, гринлет — и чекай результат когда он тебе будет нужен.

короче, все как везде.

val-amart ★★★★★
()
Ответ на: комментарий от val-amart

1) Ок, спасибо за пояснение

2)

и ты хочешь синхронно запускать задачи через селеру?

Нет. В том то и суть, что как я понял генераторы или gevent/greenlet - это в том числе механизмы обеспечивания линейно написаному, с виду блокирующему, коду работу в асинхронном режиме на подобии continuations. Не? Тоесть я хотел вызвать селеру и чтобы код был написано вроде бы синхронно, но реально исполнение текущего стекового контекста было усыплено и CPU этой машины пошел выполнять что-то другое. А потом при получении ответа сам восстановил состояние и продолжил. Не даром всякие вебсокеты в Python пишутся чуть-ли не через while true

vertexua ★★★★★
() автор топика
Последнее исправление: vertexua (всего исправлений: 1)
Ответ на: комментарий от vertexua

как я понял генераторы или gevent/greenlet - это в том числе механизмы обеспечивания линейно написаному, с виду блокирующему, коду работу в асинхронном режиме на подобии continuations. Не?

нет. генераторы это syntax sugar для итераторов. хотя на них и можно сделать coroutine. только это кооперативная, а не вытесняющая, многозадачность, т.е. ты должен явно передавать управление. рекомендую Дэвида Бизли, у него есть хорошие статьи и презенташки по теме. Про гил, кстати, тоже. а гринлеты — это грубо говоря треды на уровне юзерспейса. ты можешь их использовать чтобы добиться вытеснения при вызове блокирующего кода, но не для параллелизации выполнения computation.

Тоесть я хотел вызвать селеру и чтобы код был написано вроде бы синхронно, но реально исполнение текущего стекового контекста было усыплено и CPU этой машины пошел выполнять что-то другое

да, для этого можно использовать гринлет. или обычный нативный поток. или отдельный процесс. питон умеет сделать их все очень похожими в плане прикладного приминения. только это странная задача, конкретно с селерой — это имело бы смысл с любым нормальным синхронным внешним ресурсом, а селера это кривая попытка предоставить асинхронный интерфейс для лимитированного набора ресурсов. вот честно, просто забудь что она существует, это такой системд в мире питона — появилась от непонимания фундаментальных вещей и незнания существующих инструментов.

а, еще. я так понял ты прикладной программист? если тебя реально интересует эта тема, почитай про шедулинг и синхронизацию в ядре, а потом теоретические книги про «concurrency».

val-amart ★★★★★
()
Ответ на: комментарий от val-amart

Я просто программист на scala/java и привык к тому что я потенциально могу просто пользоваться всеми ресурсами машины, всеми ядрами без костылей и тд. В Scala могу написать монадический код, который позволит описать линейно цепочку асинхронных коллбеков с запросами в базу, внешними HTTP запросами тд. Вот пытаюсь переосмыслить все это, чтобы хоть и по другому, но так же продуктивно использовать Python

а, еще. я так понял ты прикладной программист? если тебя реально интересует эта тема, почитай про шедулинг и синхронизацию в ядре, а потом теоретические книги про «concurrency».

Да читал вроде подобное.

Вроде разница с гринлетами и генераторами в сфере кооперативной многозадачности - патчинг IO операций. Я как раз ограничиваю сферу применения, потому что да, это может быть использовано как итератор тоже. Но генератор в простых случаях похож на гринлет.

vertexua ★★★★★
() автор топика
Последнее исправление: vertexua (всего исправлений: 4)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.