Предотвращение многократного выполения консольной команды
Дата обновления перевода 2024-07-17
Предотвращение многократного выполения консольной команды
Простой, но эффективный способ предотвращения многократного выполнения одной и той же команды на одном сервере заключается в использовании блокировок. Компонент Блокировка предоставляет множество классов для создания замков, основанных на файловой системе (FlockStore ), общей памяти (SemaphoreStore ) и даже DB и серверах 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.