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

Дата оновлення перекладу 2024-05-09

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

Ви можете використовувати locks, щоб запобігти багаторазовому виконанню однієї і тієї ж команди на тому самому сервері. Компонент Lock надає декілька класів для створення блокувань у файловій системі (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;
    }
}

LockableTrait використовуватиме SemaphoreStore, якщо він доступний, і за замовчуванням використовуватиме FlockStore. Ви можете перевизначити цю поведінку, встановивши властивість $lockFactory з власною фабрикою блокувань:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// ...
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Command\LockableTrait;
use Symfony\Component\Lock\LockFactory;

class UpdateContentsCommand extends Command
{
    use LockableTrait;

    public function __construct(private LockFactory $lockFactory)
    {
    }

    // ...
}

7.1

Властивість $lockFactory була представлена в Symfony 7.1.