Компонент блокировки Symfony не блокируется в производстве

Я обновился до Symfony 3.4.*, чтобы воспользоваться преимуществами нового компонента блокировки. Однако кажется, что это работает в dev, однако в производстве блокировка всегда приобретается. Вот мой код:

Базовая командная оболочка:

<?php
namespace CoreBundle\Command;

ini_set('max_execution_time', 3600); 

use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Lock\Factory;
use Symfony\Component\Lock\Store\SemaphoreStore;

use Symfony\Component\Console\Command\LockableTrait;

class BaseCommandWrapper extends ContainerAwareCommand {

    use LockableTrait;

    function start($commandName) {

        $this->commandName = $commandName;

        $store = new SemaphoreStore();
        $factory = new Factory($store);

        $this->lock = $factory->createLock($this->commandName);

        if (!$this->lock->acquire()) {
            echo 'This command is already running in another process.' . PHP_EOL;
            return false;
        }

        echo "Lock aquired" . PHP_EOL;

        return $this->lock;
    }

    function stop() {

        echo "Releasing lock" . PHP_EOL;

        $this->lock->release();

    }

}


?>

Сама команда:

class SomeCommand extends BaseCommandWrapper
{
    protected function configure()
    {
        $this
            ->setName('processSomeCommand')
            ->setDescription('Process Some Command')
        ;
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {

        if ($this->start($this->getName()) === false) {
            return 0;
        } 

        sleep(60);

        $this->stop();

    }

Все команды запускаются cron, который в этом случае запускается каждую секунду.


person user1029829    schedule 04.01.2018    source источник
comment
Вы уверены, что ваша производственная система совместима с PHP Semaphore? php.net/manual/en/book.sem.php   -  person Benoit Galati    schedule 05.01.2018
comment
Да, однако, когда я изменил его на FlockStore, он отлично работает: $store = new FlockStore(sys_get_temp_dir()); $factory = новая фабрика ($store);   -  person user1029829    schedule 11.01.2018
comment
Мм.. Это не имеет смысла :D   -  person Benoit Galati    schedule 11.01.2018


Ответы (1)


Это может быть связано с параметром systemd RemoveIPC:

RemoveIPC= Определяет, должны ли объекты System V и POSIX IPC, принадлежащие пользователю, удаляться, когда пользователь полностью выходит из системы. Принимает логический аргумент. Если этот параметр включен, пользователь не может потреблять ресурсы IPC после завершения последнего сеанса пользователя. Это касается семафоров System V, общей памяти и очередей сообщений, а также общей памяти POSIX и очередей сообщений. Обратите внимание, что действие этого параметра исключает объекты IPC пользователя root и других пользователей системы. По умолчанию "да".

Если вы используете systemd, то каждый раз, когда cron завершается, пользователь выходит из системы, и systemd удаляет семафор.

  • Первый Cron получает блокировку
  • Второй Cron не может получить блокировку, пользователь выходит из системы, семафор удаляется
  • Трис Крон получает замок / Первый Крон его больше не имеет.

Как обсуждалось в этой ветке, либо вы отключаете RemoveIPC на своем сервере, либо используете системный пользователя, чтобы избежать этого. Или, как вы сказали в своем комментарии: используйте другой магазин.

Скорее всего, у вас должно быть предупреждение:

Предупреждение PHP: sem_remove(): семафор SysV 14071[отредактировано]0096 (больше) не существует в [отредактировано]/app/vendor/symfony/lock/Store/SemaphoreStore.php в строке 95

Кто-то еще столкнулся с проблемой: в этой теме, им, скорее всего, следует добавьте его в документацию.

person hsibboni    schedule 28.01.2020