Компонент блокировки Symfony не блокируется на производстве
Я обновился до Symfony 3.4.*, Чтобы воспользоваться новым компонентом блокировки. Однако, похоже, что он работает в dev, однако в производстве блокировка всегда получается. Вот мой код:
BaseCommandWrapper:
<?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, который запускается каждую секунду в этом случае.
0 ответов
Это может быть связано с параметром systemd RemoveIPC:
RemoveIPC= Управляет тем, должны ли быть удалены объекты IPC System V и POSIX, принадлежащие пользователю, после полного выхода пользователя из системы. Принимает логический аргумент. Если этот параметр включен, пользователь не может потреблять ресурсы 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
Кто-то еще столкнулся с проблемой: в этой ветке, скорее всего, следует добавить ее в документацию.