Скрипт вызывает сам себя с помощью ping(), образуя бесконечный цикл, т.о. обходя лимиты на время выполнения:
Но иногда скрипт перестаёт работать. Вероятно запрос ping() не доходит или ожидая эксклюзивной блокировки следующий скрипт сдыхает.
Вот первый вариант:
daemon.php
<?php
if(date('His')-file_get_contents('./date')<3)
exit;
file_put_contents('./date', date('His'));
$f=fopen('./lock', 'w+');
flock($f, LOCK_EX);
function ping($action){
$h=$_SERVER[HTTP_HOST];
$http=fsockopen($h, 80, $e1, $e2, 1);
if($http){
fwrite($http,
'GET /'.$action.' HTTP/1.1'."\r\n".
'Accept: */*'."\r\n".
'Host: '.$h."\r\n\r\n"
);
fclose($http);
}
}
ping('core.php');
sleep(3);
ping('daemon.php');
usleep(200);
flock($f, LOCK_UN);
Этот скрипт работает около 5 минут, вызывая ошибку Resource Limit Exceeded в среднем 1 раз/мин.
Вот второй, усовершенствованный вариант:
daemon.php
<?php
if(date('His')-file_get_contents('./date')<3)
exit;
$f=fopen('./lock', "w+");
flock($f, LOCK_EX);
file_put_contents('./date', date('His'));
include('./lib.inc');
ping('core.php');
sleep(3);
flock($f, LOCK_UN);
usleep(200);
ping('daemon.php');
sleep(2);
if(flock($f, LOCK_EX|LOCK_NB)){
flock($f, LOCK_UN);
sleep(15);
ping('daemon.php');
}
Этот скрипт работает около 30 минут, вызывая ошибку Resource Limit Exceeded в среднем 1 раз/15 мин.
По какой причине скрипт перестаёт работать и как это исправить?
Попытки избегания остановки:
Пробовал:
Если попробовать выполнять ping('daemon.php') рекурсивно, пока не обнаружится, что файл /lock заблокирован, т.е. следующий процесс запустился, то идет сильная нагрузка на сервер и частые ошибки 508. При этом скрипт работает не более 5 минут.
Если попробовать дважды с интервалом вызвать ping('daemon.php'), скрипт работает 30 минут.
Не пробовал:
Можно попробовать использовать два или больше сервера, вызывающих друг друга каждые 5 минут (с временем надо поэкспериментировать).
Попытки минимизации появления 508 ошибки (второстепенно):
Не пробовал:
Можно попробовать убрать эксклюзивные блокировки и оставить в качестве защиты от двойного запуска только контроль даты последнего запуска - if(date('His')-file_get_contents('./date')<3). Предполагаю, защита не выдержит и сервер нагрузится одновременными запусками.
Можно вместо блокировок использовать семафор. Предполагаю, наилучший вариант.