Задать вопрос
meteorlake
@meteorlake
Кодю код, админю домашний сервер с фильмами

Почему один запущенный процесс php влияет на второй?

Вопрос: как первый запущенный скрипт не даёт произвести INSERT в базу второму?

Есть у меня код запускаемый кроном, но при перезапуске скрипта мне нужно, чтобы старый процесс умер и новый заработал и чтобы они не работали одновременно.

В базе из нужного для этого процесса есть id(autoincrement) и status, по дефолту при добавлении status = 0

Код, который определит момент, когда можно начинать работать выглядит так:
Вносится запись нового процесса
Берётся его ID
Если в базе есть процесс с меньшим ID и статусом 1, то ждётся 1 секунда
Если в базе нет таковых, то актуальному процессу назначается статус 1

mysqli_query($GLOBALS["con"],"INSERT INTO `cronlog` (`type`) VALUES ('queue')");

$thisID = $GLOBALS["con"] -> insert_id;
$maxAttempts = 20;
While ($maxAttempts > 0) {
    // Есть ли старее ID со статусом 1?
    if ($GLOBALS["con"]->query("SELECT count(`id`) as exist FROM `cronlog` WHERE `status` = 1 AND `type` = '{$cronType}' AND `id` < $thisID")->fetch_assoc()['exist'] > 0) {
        // Если есть ждать 1 сек
        sleep(1);
    } else {
        // Если нет назначить статус
        mysqli_query($GLOBALS["con"],"UPDATE `cronlog` SET `status` = 1 WHERE `id` = $thisID");
        break;
    }
    $maxAttempts--;
}

if ($maxAttempts == 0) {
    // Если все попытки исчерпаны - выходим
    exit();
}


В свою очередь сама задача этого кода это цикл опрашивающий некоторые события (которых с примера я убрал) и после каждого цикла контролирующий нет ли нового процесса.

Если присутствует новый процесс с более высоким ID, то помечается статус 0 этому и закрывается скрипт
Если нет, то будет выжидание 1 секунды и перезапуск цикла.

While (1) {
    // Есть ID выше? - своему ID назначить статус 0 - exit
    if ($GLOBALS["con"]->query("SELECT count(`id`) as exist FROM `cronlog` WHERE `id` > $thisID AND `type` = '{$cronType}'")->fetch_assoc()['exist'] > 0) {
        mysqli_query($GLOBALS["con"],"UPDATE `cronlog` SET `status` = 0 WHERE `id` = $thisID");
        exit();
    } else {
        sleep (1); // Проблемный слип
    }
}


Но проблема в том, что если вот такой код запущу, то новый процесс не производит INSERT в базу данных и это занимает около 30 секунд, если слип убрать, то всё работает исправно.
  • Вопрос задан
  • 178 просмотров
Подписаться 2 Простой 3 комментария
Помогут разобраться в теме Все курсы
  • Skillbox
    Веб-разработчик на PHP
    9 месяцев
    Далее
  • Хекслет
    PHP-разработчик
    10 месяцев
    Далее
  • Нетология
    Веб-разработчик с нуля: профессия с выбором специализации
    14 месяцев
    Далее
Пригласить эксперта
Ответы на вопрос 1
Azurre
@Azurre
Web Developer
Вообще то такие вещи делаются через flock:
Добавляете в крон на постоянное выполнение и все. Она сам будет отслеживать, когда процесс умер и перезапускать его, без баз и приседаний:
flock -n /tmp/lockfile.lock /usr/bin/php worker.php

Если настроить завершение скрипта на 59 секунде простоя не будет вообще.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Похожие вопросы
FoodSoul Калининград
от 180 000 до 250 000 ₽
IT-Spirit Москва
от 230 000 до 320 000 ₽
от 200 000 до 290 000 ₽