Запобігання багаторазовому виконанню консольної команди

Дата оновлення перекладу 2022-11-19

Запобігання багаторазовому виконанню консольної команди

Простий, але ефективний спосіб запобігання багаторазовому виконанню однією і тієї ж команди на одному сервері полягає у використанні блокувань. Компонент Блокування надає багато класів для створення блокувань, заснованих на файловій системі (FlockStore ), спільній памʼяті (SemaphoreStore ) та навіть баз даних і серверах Redis.

На додаток, компонент Консоль надає PHP-рису під назвою LockableTrait, яка додає два зручних методи для блокування та випуску команд:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// ...
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Command\LockableTrait;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class UpdateContentsCommand extends Command
{
    use LockableTrait;

    // ...

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        if (!$this->lock()) {
            $output->writeln('The command is already running in another process.');

            return Command::SUCCESS;
        }

        // якщо ви радше зачкаєте, поки блокування не буде випущене, використайте це:
        // $this->lock(null, true);

        // ...

        // якщо воно не випущене чітко, Symfony випускає блокування
        // автоматично, коли завершується виконання команди
        $this->release();

        return Command::SUCCESS;
    }
}