PHP функция обработки ошибок времени выполнения - как?

A
На сайте с 09.08.2004
Offline
82
1604

Уважаемые форумчане. Прошу помочь советом в следующей ситуации:

Имеется довольно тяжелый скрипт на php, который запускается по крону в определенное время. Он обрабатывает данные и складывает их в базу. В связи с тем, что данные могут быть весьма разного обьема, скрипт не успевает их обработать за время max_execution_time = ххх (из php.ini) или за время set_time_limit(хх) (установленное в самом скрипте); он вылетает с ошибкой Fatal error: Maximum execution time of хх seconds exceeded in ххх. При этом естественно аварийно закрываются все открытые базы данных и файлы, и теряются все обработанные данные, которые скрипт не успел записать.

Можно ли обьявить/описать/создать блок кода или функцию, которая бы определяла, что наступило максимальное время работы скрипта или перехватывала это сообщение, записывала данные в базу(пусть даже и не все) и заканчивала работу? Либо же обьявить перехватчик этой ошибки Maximum execution time exceeded и направить его в функцию, см. выше.

Или же придется тупо проверять время выполнения скрипта(которое не может быть заранее известно) временными функциями и по концу его заканчивать работу.

Буду благодарен за дельные советы и замечания.

ЗЫ. Все возможные таймауты выставлены, подсчет примерного времени работы скрипта в зависимости от входных данных обьективно не рационален. Просьба также не предлагать увеличить время выполнения функцией set_time_limit(ххх).

Петр Елагин
На сайте с 21.03.2007
Offline
197
#1
Asher:
Просьба также не предлагать увеличить время выполнения функцией set_time_limit(ххх).

Я не буду это предлогать, но скажите почему, хостер блокирует ?

edogs software
На сайте с 15.12.2005
Offline
775
#2
Asher:
Можно ли обьявить/описать/создать блок кода или функцию, которая бы определяла, что наступило максимальное время работы скрипта или перехватывала это сообщение, записывала данные в базу(пусть даже и не все) и заканчивала работу? Либо же обьявить перехватчик этой ошибки Maximum execution time exceeded и направить его в функцию, см. выше.
Или же придется тупо проверять время выполнения скрипта(которое не может быть заранее известно) временными функциями и по концу его заканчивать работу.

1) Самое разумное: самим выставить set_time_limit в максимально допустимое значение. Допустим 60 секунд. После этого в скрипте, в критических моментах - проверять текущее время и если что аварийно завершаться. Лучше с заведомо достаточным запасом по времени.

2) "Трюковой" подход (ибо функция всё-таки не для этого). Пример:

ob_start("abazaba");

set_time_limit(1);
for($i=0;$i<=10000;$i++) $i--;
function abazaba($a) {
$a.=5;
for($i=0;$i<=100000;$i++) $b++;
$a.='-'.$i;
return $a;
}

Смысл примера вот в чем. Сначала включается буферизация вывода и функция которая вызывается когда этот вывод начинается. Когда time_limit кончится, то начнется вывод контента (он передается как параметр этой функции) и в этой функции можно сделать что угодно. Пример наглядно покажет, что даже после уже вывода фатальной ошибки о конце скрипта - будет выполнена функция abazaba и сделана приписка к контенту.

3) "Стандартный" способ: register_shutdown_function - просто регистрируете функцию и она вызывается на событии заверешния скрипта. В отличии от пункта 2 - контент уже будет выкинут в аутпут. Пункт 2 как ни странно надежнее по нашему опыту, да и контент позволяет ловить.

P.S.: Способы 2 и 3 могут не сработать если хостер просто прибивает сами процессы, а не отдает это на откуп php.

P.P.S.: Учтите, что файловые операции, операции с БД и удалёнными урлами могут не учитываться в set_time_limit. Например, если Вы ждете ответа от удалённого сервера 50 секунд, то для скрипта это время не будет считаться. Если у Вас граббер - это может быть актуально.

AlienZzzz:
Я не буду это предлогать, но скажите почему, хостер блокирует ?

Как правило что бы не блокировать если что клиента или его скрипты экстренно:) Нужен хостеру подвисший скрипт, создающий постоянную нагрузку? А клиенту нужен жестко прибитый скрипт по только что названной причине? Лимиты на время выполнение достаточно мягкий способ избежать проблем из-за ошибок в скриптах приводящих к их подвисанию и в то же время они легко обходятся в случае необходимости, плюс это способ - дающий понять клиенту сколько у его скрипта есть гарантированного времени на работу.

Разработка крупных и средних проектов. Можно с криптой. Разумные цены. Хорошее качество. Адекватный подход. Продаем lenovo legion в спб, дешевле магазинов, новые, запечатанные. Есть разные. skype: edogssoft

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий