LINUX.ORG.RU

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

 


3

7

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

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

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

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

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

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

★★★★★

Последнее исправление: vertexua (всего исправлений: 2)
Ответ на: комментарий от 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)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.