frankdejonge / locked-console-command
A symfony/console command decorator which locks.
Installs: 6 413
Dependents: 0
Suggesters: 0
Security: 0
Stars: 47
Watchers: 5
Forks: 6
Open Issues: 1
Requires
- php: >=5.5.9
- symfony/console: ~3.0
- symfony/filesystem: ~3.0
Requires (Dev)
- henrikbjorn/phpspec-code-coverage: ~1.0
- phpspec/phpspec: ~2.1
README
In some cases, you'll want only one process of a certain command to be able to run at a time. The Command decorator supplied in this package makes this possible by using the LockHandler class from Symfony's Filesystem Component.
Credits
The idea wasn't initially mine, I stole it from @Seldaek.
Installation
composer require frankdejonge/locked-console-command
Usage
All you have to do, is wrap the command:
<?php use FrankDeJonge\LockedConsoleCommand\LockedCommandDecorator; use Symfony\Component\Console\Application; $application = new Application; $app->add(new LockedCommandDecorator(new YourConsoleCommand())); $app->run();
Laravel Usage
use FrankDeJonge\LockedConsoleCommand\LockedCommandDecorator; Artisan::add(new LockedCommandDecorator(new SomeCommand()));
How does the locking work?
The decorator uses a file lock (supplied by Symfony's LockHandler) to ensure a lock is set before and released after executing the command.
If a lock is already set for a given task, an info message is shown and the decorated command is prevented from running.
Configuration
There are two configurable parts to influence locking.
- The lock name
- The lock path
Through __constructor argument injection
$command = new LockedCommandDecorator($yourCommand, 'lock-name', '/lock/path'));
Through interface implementations in the wrapper Command
- Implement
FrankDeJonge\LockedConsoleCommand\SpecifiesLockName
(::getLockName()
) - Implement
FrankDeJonge\LockedConsoleCommand\SpecifiesLockPath
(::getLockPath()
)
The SpecifiesLockName
interface is especially handy with dynamic lock names, for example:
class SomeQueueWorker extends Command implements SpecifiesLockName { public function getLockName(InputInterface $input) { return 'root:name:'.$input->getArgument('worker-id'); } }