woonem
@woonem

Как исключить остановку самовызывающегося скрипта?

Скрипт вызывает сам себя с помощью 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). Предполагаю, защита не выдержит и сервер нагрузится одновременными запусками.
Можно вместо блокировок использовать семафор. Предполагаю, наилучший вариант.
  • Вопрос задан
  • 138 просмотров
Пригласить эксперта
Ответы на вопрос 1
kimono
@kimono
Web developer
Видимо кончается выделенная память. Смотрите php.ini и замеряйте расходы памяти.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы