Skip to content

Commit 2b5dea0

Browse files
committed
[Console] Add documentation about the AsLockedCommand attribute
1 parent a183601 commit 2b5dea0

File tree

2 files changed

+110
-46
lines changed

2 files changed

+110
-46
lines changed

console/lockable_command.rst

+110
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
Prevent Running the Same Console Command Multiple Times
2+
=======================================================
3+
4+
You can use `locks`_ to prevent the same command from running multiple times on
5+
the same server. The :doc:`Lock component </components/lock>` provides multiple
6+
classes to create locks based on the filesystem (:ref:`FlockStore <lock-store-flock>`),
7+
shared memory (:ref:`SemaphoreStore <lock-store-semaphore>`) and even databases
8+
and Redis servers.
9+
10+
Using the ``#[AsLockedCommand]`` attribute
11+
------------------------------------------
12+
13+
The Console component provides an attribute called ``#[AsLockedCommand]`` that automatically
14+
sets a lock on your command, and release it when the command ends::
15+
16+
// ...
17+
use Symfony\Component\Console\Attribute\AsCommand;
18+
use Symfony\Component\Console\Attribute\AsLockedCommand;
19+
use Symfony\Component\Console\Command\Command;
20+
use Symfony\Component\Console\Input\InputInterface;
21+
use Symfony\Component\Console\Output\OutputInterface;
22+
23+
#[AsCommand(name: 'app:database:purge')]
24+
#[AsLockedCommand]
25+
class PurgeDatabaseCommand extends Command
26+
{
27+
protected function execute(InputInterface $input, OutputInterface $output): int
28+
{
29+
$output->writeln('Purging the database...');
30+
31+
return Command::SUCCESS;
32+
}
33+
}
34+
35+
.. versionadded:: 7.1
36+
37+
The ``#[AsLockedCommand]`` attribute was introduced in Symfony 7.1.
38+
39+
By default, the command name will be use as a key for the lock, but you can customize it::
40+
41+
use Symfony\Component\Console\Attribute\AsCommand;
42+
use Symfony\Component\Console\Attribute\AsLockedCommand;
43+
use Symfony\Component\Console\Command\Command;
44+
45+
#[AsCommand(name: 'app:database:purge')]
46+
#[AsLockedCommand(lock: 'my-custom-lock-key')]
47+
class PurgeDatabaseCommand extends Command
48+
{
49+
// ...
50+
}
51+
52+
If, for any reason, you need to define the lock key at runtime, you can define it with a callable::
53+
54+
use Symfony\Component\Console\Attribute\AsCommand;
55+
use Symfony\Component\Console\Attribute\AsLockedCommand;
56+
use Symfony\Component\Console\Command\Command;
57+
use Symfony\Component\Console\Input\InputInterface;
58+
59+
#[AsCommand(name: 'app:database:purge')]
60+
#[AsLockedCommand(lock: [self::class, 'getLockKey'])]
61+
class PurgeDatabaseCommand extends Command
62+
{
63+
// ...
64+
65+
public static function getLockKey(InputInterface $input): string
66+
{
67+
return $input->getArgument('lock-key');
68+
}
69+
}
70+
71+
Using the LockableTrait
72+
-----------------------
73+
74+
In addition, the Console component provides a PHP :class:`Symfony\\Component\\Console\\Command\\LockableTrait`
75+
that adds two convenient methods to lock and release commands::
76+
77+
// ...
78+
use Symfony\Component\Console\Command\Command;
79+
use Symfony\Component\Console\Command\LockableTrait;
80+
use Symfony\Component\Console\Input\InputInterface;
81+
use Symfony\Component\Console\Output\OutputInterface;
82+
83+
class UpdateContentsCommand extends Command
84+
{
85+
use LockableTrait;
86+
87+
// ...
88+
89+
protected function execute(InputInterface $input, OutputInterface $output): int
90+
{
91+
if (!$this->lock()) {
92+
$output->writeln('The command is already running in another process.');
93+
94+
return Command::SUCCESS;
95+
}
96+
97+
// If you prefer to wait until the lock is released, use this:
98+
// $this->lock(null, true);
99+
100+
// ...
101+
102+
// if not released explicitly, Symfony releases the lock
103+
// automatically when the execution of the command ends
104+
$this->release();
105+
106+
return Command::SUCCESS;
107+
}
108+
}
109+
110+
.. _`locks`: https://en.wikipedia.org/wiki/Lock_(computer_science)

console/lockable_trait.rst

-46
This file was deleted.

0 commit comments

Comments
 (0)