Эта тема на forum.dklab.ru


melihov: Запуск одного скрипта из другого
Здравствуйте!

Я написал скрипт, который стал часто упираться в max_execution_time. Отучить/оптимизировать его точно не получится, потому что скрипт этот качает кучу внешних RSS каналов и обрабатывает их, скорость тут выиграть негде. Но у меня родилась идея: что если скрипт обработает один канал, потом запуститься снова и обработает следующий, и так до последнего. Один канал то он точно успеет до max_execution_time обработать.

Звучит вроде нетрудно, но придумать как это сделать никак не могу. include() самого себя не прокатывает по понятным причинам. system() вызывает кучу несовместимостей, пишу под win, хостинг под unix, умучился. Подумал делать include через http (include("http://.../script.php")), но появилась другая проблема — очень надо чтобы этот скрипт не был доступен из веба, то есть http запросы не пройдут.

Может кто-нибудь уже такое делал? Спасибо всем заранее.
bæv:
Пишите в базу данных (или в файл -- тоже можно), что «такой-то канал уже обработан». (Кстати и информацию с каналов -- тоже можно в базу...) Скрипт запускайте cron'ом, а в самом скрипте поставьте проверку «обработан канал или нет».
melihov:
Спасибо, действенный метод. Но, по-моему, слишком радикальный. Бить, как говорится, из пушки по воробьям.

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

Плюс к тому, потребуется ещё постоянная тонкая перенастройка крона. Допустим, нужно канал добавить — лезем в крон, пишем ещё один запуск. Убрать канал — тоже самое. И т. д.
bæv:
Ещё раз: Кстати и информацию с каналов -- тоже можно в базу...
--
1. зачем Вам "ежесекундное выполнение скрипта"? (кстати, cron, вроде, так часто и не сможет запускаться)
2. зачем "постоянная тонкая перенастройка крона"? Вы ж скриптом каналы проверяете -- в скрипте ещё один канал добавится и всё.
Дмитрий Котеров:
что-то мне подсказывает что не захотят они ставить ежесекундное выполнение скрипта, качающего неизвестно чего и откуда
Я думаю, он будет еще менее рад любому другому варианту частого запуска, и прикроет Вашу лавочку гораздо раньше. :-)

надо чтобы этот скрипт не был доступен из веба, то есть http запросы не пройдут
Почему же не подойдут? Проверяйте в скрипте $_SERVER['REMOTE_ADDR'] и, если он не совпадает с адресом хостера, давайте ошибку.

В принципе, можно выставить http://ru2.php.net/ignore_user_abort и открывать соединение самим с собой по http://php.net/fsockopen по истечение какого-то промежутка времени работы, однако данный способ нельзя назвать устойчивым: достаточно хостеру рестартануть Apache, и скрипт перестанет самозапускаться.

Думаю, cron будет лучшим способом. Поставьте там set_time_limit(1000000), а чтобы не было повторных одновременных запусков, примените http://php.net/flock:


// в начале
$lockFile = fopen(__FILE__, "r");
if (!flock($lockFile, LOCK_EX|LOCK_NB)) die("Один экземпляр скрипта уже работает!");
// не закрывайте $lockFile вообще!
...

Eugene Babushkin:
Я так же согласен, что использовать CRON в данной задаче наиболее удобно и универсально. Только не нужно слишком часто его запускать, а то, как уже говорилось:
прикроет Вашу лавочку
К примеру, раз в 20 мин. вполне должно Вас устраивать.
Проходящий:
Скрипт не прекратит работу до тех пор, пока идет вывод (не верите - проверте). Можно сделать ob_implicit_flush(), и потихоньку что-либо выводить (индикатор работы, например, или просто "Здравствуй мир") хоть три часа :).

P. S. Хостеры, когда заметят, ругаться будут - это точно.
Eugene Babushkin:
Скрипт не прекратит работу до тех пор, пока идет вывод
Для чего это Вам?
Расскажите подробнее об Вашем скрипте. Где Вы хотите его использовать и для чего. А мы уже посоветуем что-то более конкретное.

P.S. В следующий раз не забывайте входить под своим ником (если это melihov, конечно), чтобы четко наблюдать, где говорит заинтересованный автор.
melihov:
Проблема, вроде, решена таки Cron'ом + flock'ом в качестве защиты от одновременного запуска (спасибо Дмитрий Котеров!). Всем остальным высказавшимся тоже спасибо.

Eugene Babushkin, выше не я писал.

Эта тема на forum.dklab.ru