1

Тема: Форкнуть поток. Костыль :)

Итак, хочу поделиться опытом небольшим )

Задача: на вход получаем файлик xml, парсим его, производим математические операции (площадь посчитать, расстроение посчитать и.т.д.), ложим в базу.
Файлик очень большой, время выполнения операции примерно 3-е суток на хетзнере дедике 4-рке.
Собственно как сделал я чтобы карсиво показать юзеру ход выполнения. После того как файлик загружен и распарсен в базу мы начинаем производить мат. операции над данными. Юзера я перекидываю на другую страницу, на этой странице я убиваю куку PHPSESSID и аяксом трекаю статус процесса, таким образом пыха работает в 1+n потоков default/smile 1 поток это сама долгая операция а N потоки это те которые трекают статус.

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

2

Re: Форкнуть поток. Костыль :)

triple1 пишет:

как в пыхе запутстиь трудоемкий поток асинхронно ?

Через обычный exec/passthru, с определенными настройками, чтобы не умирал. Вывод перенаправляется в /dev/null.
Либо как вариант - через сокеты (fsockopen), если на сервере зарезаны системные функции.

3

Re: Форкнуть поток. Костыль :)

relo_san пишет:

exec/passthru

Есть же http://symfony.com/doc/current/components/process.html

Весело тут у вас.

4

Re: Форкнуть поток. Костыль :)

Просмотрел по диагонали сам код и доку, не нашел ни слова, ни примера про асинхронный запуск. Если оно умеет запускать процесс асинхронно - ну, здорово, можно не городить велосипедов и использовать готовый компонент. Хотя по факту нужный код с exec в данном случае легко умещается в 10 строк, со всеми проверками.

5

Re: Форкнуть поток. Костыль :)

Наверное самый изящный вариант - использовать Gearman.

6

Re: Форкнуть поток. Костыль :)

ruFog пишет:

Наверное самый изящный вариант - использовать Gearman.

Для того, чтобы запустить асинхронный поток, ставим и используем менеджер очередей? default/smile
Не многовато ли, там где по факту хватит 3 строк пхп кода?.. Из пушки по воробьям.

Re: Форкнуть поток. Костыль :)

relo_san пишет:

Для того, чтобы запустить асинхронный поток, ставим и используем менеджер очередей?
Не многовато ли, там где по факту хватит 3 строк пхп кода?.. Из пушки по воробьям.

Или пишем свой класс по pid определяем запущен поток или нет. С gearman можно масштабировать, особенно если вычисления занимает столько много времени.

8

Re: Форкнуть поток. Костыль :)

SymfonyProger пишет:

С gearman можно масштабировать, особенно если вычисления занимает столько много времени.

Далеко не всякие вычисления можно масштабировать. Если стоит задача масштабировать, и вычисления позволяют распараллелить процесс - тогда да, можно использовать любой подручный менеджер очередей, без разницы какой. Но если стоит задача запустить какую-то хрень в одном процессе, то менеджер очередей здесь так же уместен, как база данных для хранения одного текстового поля.

P.S. В контексте одного физического сервера распараллеливание ресурсоемкого процесса, даже если оно возможно, будет ограничено суммарным количеством ядер установленных в него процессоров. С поправкой на то, что загрузить все ядра этой одной задачей - плохая идея, остальные сервисы начнут дико тормозить, также с ростом параллельных процессов увеличится нагрузка на БД.

Re: Форкнуть поток. Костыль :)

relo_san пишет:

Далеко не всякие вычисления можно масштабировать. Если стоит задача масштабировать, и вычисления позволяют распараллелить процесс - тогда да, можно использовать любой подручный менеджер очередей, без разницы какой. Но если стоит задача запустить какую-то хрень в одном процессе, то менеджер очередей здесь так же уместен, как база данных для хранения одного текстового поля.

P.S. В контексте одного физического сервера распараллеливание ресурсоемкого процесса, даже если оно возможно, будет ограничено суммарным количеством ядер установленных в него процессоров. С поправкой на то, что загрузить все ядра этой одной задачей - плохая идея, остальные сервисы начнут дико тормозить, также с ростом параллельных процессов увеличится нагрузка на БД.

Я бы взял отдельный дедик и делал бы там вычисления. Если не нужно масштабировать то пишем свой класс, при этом проверяя pid

10

Re: Форкнуть поток. Костыль :)

SymfonyProger пишет:

Я бы взял отдельный дедик и делал бы там вычисления.

Отлично, учитывая что у вас нет исходных данных о том, что за задачи выполняются, для чего, какие временные рамки...
Т.е. грубо говоря - если вам нужно раз в неделю/месяц что-то объемное посчитать и время выполнения расчетов вас устраивает - то вы все равно побежите брать новый сервер в аренду за кровные сотни баксов. У вас наверно дофига ненужных зеленых бумажек.

11

Re: Форкнуть поток. Костыль :)

Асинхроно запустить то можно, и даже без проблем, но вот другой вопрос: нужно ли это?

Пример аснихроного вызова:

php /path/to/you-script.php arg1 arg2 arg3 > /dev/null &

Или же вывод в какой-то файл

А здесь еще нужно подумать, как контролировать статус (Ну к примеру процент выполнения и т.д.).
Лучше всего это будет сделать в каком-то отдельном хранилище (redis, memcached) доступ до которых можно получить отовсюду. И тогда в асинхроном скрипте все туда пишешь, а в простом уже просто читаешь default/smile

А если поиграться хочешь, то можно запустить точно также ассинхронно, но потом еще и поднять socket server, который будет отвечать за статусы default/smile
И тогда, если коннект был, то ура, скрипт работает и ты имеешь туда полные доступ, включая даже можешь изменять все параметры ...

Re: Форкнуть поток. Костыль :)

triple1 пишет:

Задача: на вход получаем файлик xml, парсим его, производим математические операции (площадь посчитать, расстроение посчитать и.т.д.), ложим в базу.
Файлик очень большой, время выполнения операции примерно 3-е суток на хетзнере дедике 4-рке.
Собственно как сделал я чтобы карсиво показать юзеру ход выполнения. После того как файлик загружен и распарсен в базу мы начинаем производить мат. операции над данными. Юзера я перекидываю на другую страницу, на этой странице я убиваю куку PHPSESSID и аяксом трекаю статус процесса, таким образом пыха работает в 1+n потоков  1 поток это сама долгая операция а N потоки это те которые трекают статус.

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

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

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

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

P.S. Gearman, конечно, правильнее, если задач может быть много - проще масштабировать.

13

Re: Форкнуть поток. Костыль :)

ZhukV пишет:

Асинхроно запустить то можно

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

Странник пишет:

P.S. Gearman, конечно, правильнее

Gearman не нужен, его функции вполне заменит просто Redis + библиотека php-resque. Хотя и мешать он конечно тоже не будет, свою работу выполнит, но в основном это лишнее звено. А для более серьезных задач и нагрузок лучше поставить RabbitMQ.

14

Re: Форкнуть поток. Костыль :)

О, заодно и я отвечу.

https://github.com/symfony/symfony/pull/8753

relo_san пишет:

Просмотрел по диагонали сам код и доку, не нашел ни слова, ни примера про асинхронный запуск. Если оно умеет запускать процесс асинхронно - ну, здорово, можно не городить велосипедов и использовать готовый компонент. Хотя по факту нужный код с exec в данном случае легко умещается в 10 строк, со всеми проверками.

Оно умеет, proc_open как-бы вполне асинхронен, думаю не нужно кидать ссылку на доку.

Так-же сейчас висит следующий пр https://github.com/symfony/symfony/pull/8753, который скорее всего уже будет в 2.4.

relo_san пишет:

Gearman не нужен, его функции вполне заменит просто Redis + библиотека php-resque. Хотя и мешать он конечно тоже не будет, свою работу выполнит, но в основном это лишнее звено. А для более серьезных задач и нагрузок лучше поставить RabbitMQ.

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

Весело тут у вас.

15

Re: Форкнуть поток. Костыль :)

Dark пишет:

Если в проекте не заюзан редис, то первый вариант вообще отпадает

Да, согласен. Ставить редис с огородами только ради реализации очереди смысла нет, кролика проще. Просто у меня во всех проектах за последние пару лет редис используется.