В общем ситуация такая. Есть скрипт, который может работать в некоторых редких случаях больше чем интервал в cronjob, но запускать его при этом нужно каждую минуту, так как в 95% случаев он отрабатывает за несколько секунд. Нужно исключить возможность повторного запуска.
Сразу оговорюсь, это бесплатный хостинг, поэтому SSH доступа нет, и мониторить процессы не получается. Остаётся лишь реализовать это средствами PHP
Пробовал так
//Статический файл который будет хранить имя временного файла
$lockFilename = __DIR__ . '/lock.dat';
//Проверяем существует ли временный файл
if (file_exists($lockFilename) && ($lock = file_get_contents($lockFilename)) && file_exists($lock)) {
echo "Cron running now {$lock}
";
exit();
}
//Файл должен умереть при закрытии дескриптора
$tmpHandle = tmpfile();
//Получаем имя временного файла
$metaData = stream_get_meta_data($tmpHandle);
//Записываем имя временного файла в статический файл
file_put_contents($lockFilename, $metaData['uri']);
//Cron симуляция
echo "Cron started
";
sleep(20);
echo "Cron stopped
";
exit();
Но файл остаётся, если прервать скрипт через Ctrl+C
Думал решить задачу через memcache и время жизни ключа, но обратно таки бесплатный хостинг не предоставляет memcache в распоряжение
Ответ
Вариант с блокировкой файла:
$fp = fopen("lock", "w+");
if (flock($fp, LOCK_EX | LOCK_NB)) { // выполняем блокировку
/*
* Тут код который нужно выполнить
*/
flock($fp, LOCK_UN); // отпираем файл
} else {
echo "Не удалось получить блокировку, файл уже заблокирован!";
}
fclose($fp);
unlink("lock");
Вариант с обработкой сигналов:
declare(ticks = 1); // включить обработку сигнала
function sigint() {
exit();
}
pcntl_signal(SIGINT, 'sigint');
pcntl_signal(SIGTERM, 'sigint');
/*
* Тут код который нужно выполнить
*/
Комментариев нет:
Отправить комментарий