Symfony,在一个命令中设置锁定以锁定另一个命令

ss2ws0br  于 2022-11-16  发布在  其他
关注(0)|答案(1)|浏览(209)

在Symfony 4.4上,我试图在命令中建立一个锁,并在显式释放之前保持它的活动状态。阅读文档后,我了解到这应该通过Symfony\Component\Lock\LockFactory::createLock()$autoRelease参数获得,但似乎即使我设置了$autoRelease = false,锁也会在脚本结束时自动释放。

LockCommand

<?php
namespace App\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Lock\LockFactory;

class LockCommand extends Command
{
    const LOCK_NAME = "my_lock";

    protected static $defaultName = 'app:lock';

    private $lockFactory;

    public function __construct(LockFactory $lockFactory)
    {
        $this->lockFactory = $lockFactory;
        parent::__construct();
    }    

    protected function configure()
    {
        $this
            ->setDescription("Enables/disables the lock.")
            ->addOption(
                'release',
                'r',
                InputOption::VALUE_NONE,
                'Releases the lock'
            )
        ;
    }    

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $lock = $this->lockFactory->createLock(self::LOCK_NAME, 300.0, false);

        $release = $input->getOption('release');
        
        if ($release) {
            $lock->release();
        } else {
            $lock->acquire();
        }

        //sleep(300);

        return 0;
    }    
}

LockVerifyCommand(四个月前)

<?php
namespace App\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Lock\LockFactory;

class LockVerifyCommand extends Command
{
    protected static $defaultName = 'app:lock-verify';

    private $lockFactory;

    public function __construct(LockFactory $lockFactory)
    {
        $this->lockFactory = $lockFactory;
        parent::__construct();
    }    

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $lock = $this->lockFactory->createLock(LockCommand::LOCK_NAME, 300.0, false);
        $status = $lock->acquire() ? "no" : "yes";
        $output->writeln("Locked? $status");

        return 0;
    }
}

我希望能够
1.启用锁定php bin/console app:lock

  1. php bin/console app:lock-verify应该是Locked? yes
    1.直到我释放锁php bin/console app:lock --release
    只有在运行app:lock命令时才会发生这种情况。
c2e8gylq

c2e8gylq1#

这里最重要的是LockStore的实际实现。取决于您选择哪一个,可能意味着完全不同。
例如,如果我没记错的话,LockStore默认为SemaphoreStore。您可以在GitHub上查找代码,但主要要注意的是,它使用了PHP的ext-semaphore扩展(即sem_*函数)。查看PHP的sem_acquire文档页面,它显示:
在处理请求后,将自动释放进程获取但未显式释放的任何信号量,并生成警告。
换句话说,在主进程结束后,锁不会持久化。
FileStore也是如此,尽管它完全取决于操作系统来释放锁,这可能会变得混乱。
您需要的是一些持久性存储,如PdoStoreDoctrineDbalStoreRedisStore或其他。
不过要注意的是,有些商店的锁会自动过期。你可以在官方文档页面上阅读更多相关信息:到期锁定

相关问题