Требуется ваша критика такого подхода к реализации управления тяжелыми фоновыми задачами

Aleks_P

Новичок
Суть такая. Пишется относительно легкая видео КМС. Пользователь имеет возможность запустить конвертирование видео, а также имеет некие аналоги операций как в проводнике: перемещение, копирование внутри своих виртуальных папок. Допустим он подает команду на конвертирование видео. Замечу, что видео могут быть очень тяжелые, вплоть до десятка гигабайт. Т.е. время выполнения может быть и сутки. Серверу отправляется запрос, этот запрос оформляется в виде задачи и добавляется в список задач. Далее, по крону раз в несколько минут запускается некий менеджер задач, который, выбрав очередную задачу, должен запустить её в фоне и, не дожидаясь её завершения, завершить свою работу. Таким образом менеджер задач может запустить параллельно допустим три задачи. Кол-во параллельных задач можно варьировать в зависимости от мощности/загруженности сервера. Более того, каждый текущий процесс должен слушать сообщения от менеджера задач, которые тот может отправлять на проверку завис ли процесс, если ответ от процесса пришел, то всё нормально, иначе - инициируем принудительное его завершение. Также процесс должен периодически составлять отчеты о текущем прогрессе своей задачи. Благодаря последнем, пользователь может наблюдать у себя в реальном времени текущий прогресс выполнения.

Сразу скажу, что к профи я не отношусь. :) Как я вижу архитектуру такого приложения.

Менеджер задач.

Все задачи, складируются в БД. Во-первых, проверяем был ли завершён предыдущий запуск менеджера, если нет, то оставляем сообщение в логах и выходим. Если всё ок, следуем далее. Проверяем сколько у нас уже активных задач. Читаем от них сообщения. Если от какой-то задачи нет ответа пытаемся завершить её путем отправки kill соответствующему процессу. Не ждем результата. Снова оставляем сообщения. Затем если ещё допустимо запустить другие задачи, то берем первую ожидающую задачу и запускаем скрипт-процесс таким образом:

system ( "/usr/local/bin/php proccess.php?taskid=3556 > /dev/null 2>&1 &" );

На этом основные обязанности менеджера задач выполнены. Завершаем его работу.

Процесс.

Выборка задачи из БД. Инициализация. set_time_limit ставим побольше, например, в несколько часов. Можно эту величину сделать в зависимости от типа задачи. Допустим, текущая задача заключается в конвертировании видео. Значит лимит ставим максимальным - неограниченное выполнение. Кодировать будем ffmpeg’ом. Запускаем его точно также без ожидания результат, но после запуска уходим в цикл ожидания. В цикле выполняем следующие действия:

1. Проверяем сообщения от менеджера задач. Отвечаем, что всё нормально - работаем.

2. Смотрим логи ффмпега, соответственно получаем информацию о текущем прогрессе. Составляем отчет. Анализруем на предмет его подвисания.

и далее покругу.
 

Absinthe

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

grigori

( ͡° ͜ʖ ͡°)
Команда форума
а. у php есть неприятная особенность: sleep() кушает проц похоже, исправили
б. а есть ли смысл форкать proccess.php, если он точно так же запустит ffmpeg?
в. при вызове `proccess.php?taskid=3556` скрипт никакого taskid не получит :)
г. "периодически составлять отчеты" - а кто и зачем их будет использовать, кроме как для дебага? для пользователя отчет нужен по результату
д. если от какой-то задачи долго нет ответа потому что тяжелый ролик обрабатывается, а ты ее kill - потеряли ролик, засрали диск временными файлами
и т.д.

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

Aleks_P

Новичок
б. Есть. Зачем всё смешивать в одну кучу? Принцип разделения обязанностей: менеджер процессов управляет процессами, каждый процесс контролирует конкретно свою задачу. Удобно. Можно реализовать в виде классов.
в. На самом деле я имел ввиду передачу параметров через командную строку proccess.php -taskid
г. Про отчеты по результатам я и говорил. Было написано: "Также процесс должен периодически составлять отчеты о текущем прогрессе своей задачи. Благодаря последнем, пользователь может наблюдать у себя в реальном времени текущий прогресс выполнения."
д. Что мешает периодически чистить папку с временными файлами в моменты когда нет задач? Или же просто грамотнее реализовать принудительное завершение задач. Тот же ффмпег при кодировании пишет сразу в результирующий файл, который можно просто удалить в таком случае.
 
Сверху