2017-12-12 32 views
3

最近、Symfony 3.4.x、リファクターLockHandlerにアップグレードされました。これは非推奨の警告であり、奇妙な動作になります。リファクタリング前のコマンドでSymfony Lock Componentはロックされません - 修正方法?

コード:

class FooCommand 
{ 
    protected function configure() { /* ... does not matter ... */ } 
    protected function lock() : bool 
    { 
     $resource = $this->getName(); 
     $lock  = new \Symfony\Component\Filesystem\LockHandler($resource); 

     return $lock->lock(); 
    } 
    protected function execute() 
    { 
     if (!$this->lock()) return 0; 

     // Execute some task 
    } 
} 

は、そして、それは同時に2つのコマンドを実行しないように - 第二は、ちょうど仕事をしなくて終わります。それはいいです。

しかし、リファクタリングを推奨した後、同時に多くのコマンドを実行することができます。これはFAILです。実行を防ぐ方法は?新しいコード:

class FooCommand 
{ 
    protected function configure() { /* ... does not matter ... */ } 
    protected function lock() : bool 
    { 
     $resource = $this->getName(); 
     $store = new \Symfony\Component\Lock\FlockStore(sys_get_temp_dir()); 
     $factory = new \Symfony\Component\Lock\Factory($store); 
     $lock  = $factory->createLock($resource); 

     return $lock->acquire(); 
    } 
    protected function execute() 
    { 
     if (!$this->lock()) return 0; 

     // Execute some task 
    } 
} 

NB#1:私は多くのサーバーほど気にしません。アプリケーションのインスタンスは1つだけです。

NB#2:プロセスが強制終了された場合、新しいコマンドはロックを解除して実行する必要があります。

答えて

3

あなたは

use Symfony\Component\Console\Command\LockableTrait; 
    use Symfony\Component\Console\Command\Command 

    class FooCommand extends Command 
    { 
     use LockableTrait; 
..... 
protected function execute(InputInterface $input, OutputInterface $output) 
    { 
     if (!$this->lock()) { 
      $output->writeln('The command is already running in another process.'); 

      return 0; 
     } 
// If you prefer to wait until the lock is released, use this: 
     // $this->lock(null, true); 

     // ... 

     // if not released explicitly, Symfony releases the lock 
     // automatically when the execution of the command ends 
     $this->release(); 

} 
+0

ありがとうLockableTrait形質を使用する必要があります!良い仕事。ドキュメントにはこれが含まれていないのは悲しいことです。 – trogwar

+1

「LockableTrait」は実際にはSymfony Consoleコマンドのヘルパーにすぎないことに注意してください。ロックストアは2つしか実装されておらず、どちらもローカルです。それらは 'FlockStore'と' SemaphoreStore'ストアです。これは 'MemcachedStore'や' RedisStore'では動作しません。後者のストアのいずれかが必要な場合、 'LockableTrait'は助けにならないでしょう。 – danemacmillan

+0

ありがとうございます。私は特性の源を見ました - それは本当に簡単です。私の目的のためには、十分なローカルストレージ。 – trogwar

関連する問題