2017-12-12 20 views
3

최근에 Symfony 3.4.x로 리팩터링 된 LockHandler가 사용 중단 경고로 인해 이상한 동작으로 바뀌 었습니다. 리팩토링 이전 명령Symfony 잠금 구성 요소가 잠기지 않습니다 - 해결 방법은 무엇입니까?

코드 :

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 
    } 
} 

는 그리고 동시에 두 개의 명령을 실행 방지 - 두 번째는 일을하지 않고 완료됩니다. 좋습니다.

그러나 제안 된 리팩토링 이후에 많은 명령을 동시에 실행할 수 있습니다. 이것은 불합격입니다. 실행을 방지하는 방법? 새 코드 :

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 : 많은 서버가 신경 쓰이지 않습니다. 응용 프로그램이 하나만 있습니다.

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 콘솔 명령을 돕는 역할을합니다. 그것은 단지 두 개의 잠금 저장소를 구현하며 둘 다 로컬입니다. 그것들은'FlockStore'와'SemaphoreStore' 저장소입니다. 이것은'MemcachedStore' 또는'RedisStore'에서는 작동하지 않습니다. 후자의 매장 중 하나가 필요하다면,'LockableTrait'는 도움이되지 않을 것입니다. – danemacmillan

+0

감사합니다. 나는 특성의 근원을 보았다 - 그것은 정말로 간단하다. 나의 목적을 위해, 충분히 로컬 스토리지. – trogwar