Страницы

Поиск по вопросам

суббота, 15 июня 2019 г.

Запустить скрипт только один раз?

В общем ситуация такая. Есть скрипт, который может работать в некоторых редких случаях больше чем интервал в 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');
/* * Тут код который нужно выполнить */

Комментариев нет:

Отправить комментарий