Как стать автором
Обновить

Комментарии 53

А есть то же самое, но на каком-нить гитхабе?
вечером могу выложить
пришлось немного потупить — никогда не работал с github, но вроде разобрался. Вот github.com/xzag/php-pm
О, спасибо!
Я смотрю, тут всё упражняются с костылями :)
Без иронии, я интересовался «зрелыми» и «некостыльными» решениями по этой теме, но, к сожалению, пока не нашел того, что бы меня полностью устраивало [это, пока еще не проверял]. Если у вас есть ссылки на хорошие решения — поделитесь. Или, еще лучше, воспользуйтесь recovery и напишите развернутый топик.
О чем писать развернутый топик, если php не предназначен для этой цели?
НЛО прилетело и опубликовало эту надпись здесь
Хм… ну давайте я попробую предложить ситуацию, где это нужно. Почти из жизни.
Есть сайт и есть не совсем тривиальные модели, которые уже реализованы в php.
И есть асинхронные задачи, требующие эти модели, например, банальная перекодировка/создание превьюшек для загруженных данных.
На текущий момент самым практичным мне видется формирование демонизированных воркеров на php с каким-нибудь gearman'ом во главе. Ваши предложения?
Переписать часть бэкенда на что-то более подходящее для этой цели. python, например. Я не являюсь адептом какого-либо из языков, но у любого инструмента есть своя область применения. Понятно, что иногда в уже сложившихся условиях приходится искать компромиссное решение, но в большинстве случаев «лучше день потерять, потом за 5 минут долететь».
Т.е. вы предлагаете (возьмем python)
а) переписать требуемые модели на python, после чего стараться не забыть обновить их в случае обновления на сайте и поддерживать две ветки одновременно
б) переписать сайты на python, переквалифицировать/уволить имеющихся программистов и жить счастливо с более лучшим языком (объяснив по ходу инвестором, чем это мы все это время занимаемся) потому, что «в кузнице не было гвоздя»
Ну, конечно, можно пойти и таким путем, но я пока поищу решения подешевле.
Я предлагаю вариант а), но немного не так его себе вижу. При наличии некого интерфейса обмена данными переписывать/обновлять бэкэнд придется только в том случае, когда меняется сам интерфейс (например, расширяется или оптимизируется). Ну а изменения в интерфейсе будут настолько очевидны, что забыть про бэкэнд не выйдет. У моего предыдущего работодателя фронтенд был на php, бэкэнд по большей части на perl. Когда в php упирались в определенные ограничения, то product owner'у объяснялось, что есть два пути развития костыльный и потенциально тупиковый (но относительно быстрый) и «прямой» (но относительно долгий). Когда у владельца продукта есть возможность оценить все «за» и «против», он с большой вероятностью согласится на отдельный бэкэнд вместо костылей.

Вариант б) я не предлагаю, потому что мало какой инвестор/продактоунер согласится на него (я бы тоже не согласился :)). Правда, в реальном мире я знаю как минимум один пример применения подхода б).

p.s. У минусаторов изначального коммента слишком много серьезности в голове. Смысл коммента сводился к тому, что таких вещей надо по возможности избегать.
Я рад, что в треде появилось немного конструктивизма.

К сожалению, в моих реалиях есть китайцы, общением с которыми и занимаются те самые модели (построенные, надо заметить, частично на багах апи и реверс-инженеринге) и на стабильность интерфейсов в требуемых масштабах времени расчитывать не приходится.
Т.о. придется таки тратить немало усилий по поддержке моделей.
Давайте по пунктам чем python лучше php для подобной задачи? Это я на основе опыта перехода с асинхронного python на gearman + php спрашиваю.
Тем, что код, написанный автором, а так же множество других сопряженных с ним фич, реализованы в стандартном модуле multiprocessing, который широко протестирован, стабилен и поддерживается самим питоном. Простым выбором нужного класса Pool-а вы можете выбрать мультипроцессную, мультизадачную или кооперативную многозадачность. Они написаны и отлажены в тысячи проектов.

В PHP — чисто из практических соображений, скажите честно, вы бы хотели иметь в проекте код, подобный коду из статьи, сопровождать и поддерживать его?
Передергиваете.
Почему у вас в питоне вдруг модуль, а в пхп код, который нужно поддерживать?
Не авторский, так чей другой, но в любом случае работающий как отдельная библиотека.
Я дал ссылку на модуль из стандартной библиотеки. Он из builtins питона.
А в чем идейная разница между модулем из стандартной библиотеки и подключаемой либой, которую не ты поддерживаешь?
По аналогии c c++ std:: и boost::
Вы абсолютно правы в том, что между std:: и boost: разницы мало. Обе поддерживаются сообществом, обе используются в тысячах проектов. Обе имеют обширную и исчерпывающую документацию.

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

Или же с чисто практической точки зрения выгодней взять стандартное решение, которое поддерживается сообществом, которое протестировано десятками юниттестов и апробировано в тысячах проектов?
Резюмируя: одному решению вы доверяете сильно больше другого.
MadJeck спрашивал о другом, не об использовании конкретно кода из данной статьи.

Что касается вашего вопроса:
В ближайшие дни я внимательно изучу код автора, и, если он оправдает надежды (ну или один раз подправив до кондиции) использую его без смущения. Т.к. в моем случае (есть выше) это будет практичнее, несмотря на то, что питон меня не страшит.
НЛО прилетело и опубликовало эту надпись здесь
А откуда по вашему появляются многие стандартные используемые всеми библиотеки? Это такой же код написанный такими же программистами, а не принесенный богами на нашу грешную землю. Просто этот код уже используется, проверен людьми, проектами и временем. Новые решения тоже требуют проверки, может сейчас это и костыль, но кому-то он может быть полезен и со временем станет такой же используемой всеми библиотекой ) И дело не в том лучше язык или хуже, важно что в нем есть такое решение, которое может кому-то понадобиться в разных ситуациях.
Для перекодировки превьюшек достаточно стадартизировать входные и выходные данные, которые потом обработать на любом ЯП. Синхронизацию можно сделать тысячью способов: БД, пайп, сокет, много еще чего. Полные модели для перекодировки… Зачем?
Это был пример. Вероятно, не самый удачный.
А какой более удачный?
Вытягивание и обработка событий, привязанных к пользователям, из совокупности источников в виде XMLRPC API и внешней бд, структура которых может непредсказуемо меняться. Для них существуют успешно функционирующие и обновляемые модели в php, совсем не в виде AR. Push'а как такового нет, только pull. Событий много.

Решение в виде переписывания модели на питоне — 1. сложно само по себе, 2. потребует дополнительной поддержки
Решение в виде расслоения с подготовкой данных питоном и последующей обработкой php — 1. сложно, 2. все-таки потребует механизмов фонового выполнения php кода.
Это реальный пример? Возьмите меня на работу!
обычно исходя из задачи выбирают технологии для её решения, а не как вы за уши притянули кейс, что без нецелевом использоваании php не обойдешься
Кейс вполне реальный. Если и не большинство сайтов на PHP, то много уж точно и задачи асинхронной обработки на них возникают нередко, хотя бы Q&A можно посмотреть. Во многих случаях реализация не на PHP вызовет задержки реализации, увеличения стоимости поддержки и развития. Хорошо, конечно, если у вас разработчики моментально переключаются между десятком языков, знают какой в каких ситуациях использовать (и даже поважнее знания собственно языка знания есть ли в его стандартной библиотеки нужные функции из коробки или сторонние популярные модули/библиотеки/фреймворки), знают все плюсы и минусы каждого из более-менее разумного варианта. А кроме разработчиков ещё и админы с легкостью администрируют гетерогенную среду. Но зачастую всего этого нет и надо или нанимать, или обучать, но тогда решение идеальное с точки зрения технического обоснования может быть далеко не идеальным с точки зрения экономического. Исходить, с точки зрения бизнеса, нужно прежде всего из доступных ресурсов на решение задачи и дохода, который её решение принесёт.
>>Исходить, с точки зрения бизнеса, нужно прежде всего из доступных ресурсов на решение задачи и дохода, который её решение принесёт.

Согласен с вами
Что значит «не предназначен для этой цели»? Если инструмент позволяет решать задачи — почему «не предназначен»?

Если уж на то пошло, то Вы, видимо, не применяете js на сервере, а многие используют и довольны результатом. Ну а применять файлы для хранения данных (включая кеш) — вообще великий грех?

И не надо говорить про микроскоп и гвоздь — если я кувалдой забиваю гвозди быстрее, чем самым навороченным молотком, мне подходит именно кувалда, хотя «она не предназначена для этого»…
В третьем абзаце вы ответили на вопросы первого абзаца.

А второй абзац из области ясновидения и домыслов. Без комментариев.
Это почему не предназначен? Все используемые функции (в основном из ext/pcntl и ext/posix) являются врапперами соответствующих сишных функций. Практически 1 к 1. Может, C не предназначен для этой цели?
Ну как же! Нет специальной ООП обёртки для всего этого добра в стандартной либе. Ужас, приходится иметь дело напрямую с биндингами к функциям ядра.
То что он для WEB, не мешает на нём отлично писать консольные скрипты и приложения, т.к. с PHP 5.3 допилили менеджер памяти, добавили сборку мусора и вообще довели CLI до состояния, когда оно особо то и не отличается от того же голого python или ruby. Другое дело что наработок и библиотек практически нету, но это не вина самого языка. Да и нету такой большой необходимости этим заниматься вне WEB проектов. А когда у вас WEB проект, да на Zend/Symphony/Yii, то там есть консольные компоненты и утилиты для запуска таких процессов в контексте проекта (насчёт Zend не уверен, Symphony насколько я знаю такое имеет, а с Yii сам работаю и у него есть 2 вида компонент: CConsoleCommand и CConsoleApplication). Они просты и большее от них редко требуется. А мне вот потребовалось и я быстро и легко допилил себе консольный демон с форками, сигналами и прочей лабудой — пиши тока логику и не парься — ничего сложного там нету. Нужно просто знать и понимать как нужно писать приложения такого рода.

Код у автора статьи далеко не лучший пример — это скорее показать что можно, но дальше нужно думать самому. Да и без фреймворка будет уныло.

З.Ы. А ещё есть phpDaemon
У Zend тоже есть — Zend_Tool_Framework
может не в полной мере как в статье, но для управления и демонизации php воркеров можно использовать supervisord (правда решение не на php)
много кода, мало описания(
да, мне тоже так показалось, но я постарался дать «говорящие» имена методам и переменным, чтобы можно было без лишних слов разобраться непосредственно в коде.
Всё же лучше было описать что умеют делать ваши классы и их технологические плюсы.

Мне действительно интересна тема системного программирования в php, но читать длинную простыню кода совершенно нет никакого желания.

Пожалейте нас… :)

PS Спасибо за статью, будем тестировать.
Поддержу предыдущего оратора. Имхо, на Хабре стоит приводить только наиболее интересные фрагменты кода, если его длина больше сотни-другой строк. А даже если не больше, то всё равно стоит подумать о фрагментах, а не о «цитировании» полных файлов. При всём уважении к желанию (и смелости) поделиться своими наработками на Хабре, это не место для непосредственного обмена кодом, даже хорошо прокомментированным (про комментарии вида ./*while ($this->isRunning()) {
echo '.';
sleep(1);
}*/ промолчу).

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

P.S. А почему именуете приватные переменные с префиксом _?
учту.

отвечу на последний вопрос: исторически полюбившийся метод именования всех непубличных переменных таким образом. В подсознании возникает четкое понимание — раз подчеркнуто значит это чье-то и лучше напрямую не лезть.
>P.S. А почему именуете приватные переменные с префиксом _?

Не только переменные, но и методы.

Такой стиль используется в Zend Framework, хотя и не является частью их стандарта кодирования (по-крайней мере явно).
спасибо за ссылку, постараюсь ознакомиться
Большое спасибо, очень полезно!
Автору спасибо!
[sarcasm]Развели флейм в каментах, как обычно. Каждому не терпится сообщить, что с PHP он завязал и теперь по взрослому пишет на Python — очень ценная информация. [/sarcasm]
+1. И вообще, такое ощущение, что теперь любой пост про пхпх будет заканчиваться каментами, чем питон круче пхп
Побуду некропостером :)

> while ($line = fgets($this->_pipes[$index])) {

С этим кодом есть одна проблема — он будет продолжать читать пайп до тех пока не встретиться EOF, для proc_open это возможно только при закрытии пайпа — т.о. о полноценной двусторонней коммуникации между процессами можно забыть. Точно такая же проблема характерна для и для fread и остальных функций — если указано кол-во байт большее чем доступно в данный момент, чтение будут продолжать пока все они не будут получены или не встретиться EOF => получить все доступные сейчас данные сейчас просто невозможно (в читающем процессе нет возможности узнать сколько байт было послано).

Единственное извращение которое удалось придумать — обмениваться отдельными строками с сериализованными данными (с обязательным добавлением EOL-а при записи в пайп). Если у кого-то есть другие идеи буду рад услышать…
Такой проблемы нет. Для этого в коде используется stream_set_blocking
Ага, ошибся. Но все оказалось проще (или скорее хуже) — для пайпов открытых через proc_open stream_set_blocking вообще не работает под win :( (https://bugs.php.net/bug.php?id=47918, bugs.php.net/bug.php?id=34972, bugs.php.net/bug.php?id=51800) хоть бы написали что-ли где об этом… Впрочем под win так же присутствует «взаимная блокировка» (stream_select вообще странные результаты возвращает) при одновременном(ой) чтении(записи) в STDOUT и STDERR (https://bugs.php.net/bug.php?id=51800) что делает взаимодействие между процессами практически невозможным (осталось поэкспериментировать с файлами вместо пайпов).
У меня почему-то 100% нагрузки на одно ядро процессора (если ядер несколько), но только если процесс-менеджер запускается через crontab. Если просто с bash вызвать, то такой проблемы нет. CentOS 6.6 64bit, VPS (один на firstvds.ru, OpenVZ, второй на DigitalOcean, KVM). И на выделенном сервере с CentOS 6.5 + CloudLinux тоже самое.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации