Prevents overlapping for Laravel console commands.
PHP >=5.5.9
Laravel >=5.2
-
Install package through
composer
:composer require illuminated/console-mutex
-
Use
Illuminated\Console\WithoutOverlapping
trait in your console command class:namespace App\Console\Commands; use Illuminate\Console\Command; use Illuminated\Console\WithoutOverlapping; class Foo extends Command { use WithoutOverlapping; // ... }
-
Now your command is protected against overlapping:
➜ php artisan foo:bar baz Command is running now!
Overlapping can be prevented by various strategies:
file
(default)mysql
redis
memcached
Default file
strategy is fine for a small applications, which are deployed on a single server.
If your application is more complex and, for example, is deployed on a several nodes, then you probably would like to use some other mutex strategy.
You can change mutex strategy by specifying $mutexStrategy
field:
class Foo extends Command
{
use WithoutOverlapping;
protected $mutexStrategy = 'mysql';
// ...
}
Or by using setMutexStrategy
method:
class Foo extends Command
{
use WithoutOverlapping;
public function __construct()
{
parent::__construct();
$this->setMutexStrategy('mysql');
}
// ...
}
Sometimes it is useful to set common mutex for a several commands. You can easily achieve this by setting them the same mutex name.
By default, mutex name is generated based on a command's name and arguments. To change this, just override getMutexName
method in your command:
class Foo extends Command
{
use WithoutOverlapping;
public function getMutexName()
{
return "icmutex-custom-name";
}
// ...
}
Note, that WithoutOverlapping
trait is overriding initialize
method:
trait WithoutOverlapping
{
protected function initialize(InputInterface $input, OutputInterface $output)
{
$this->initializeMutex();
}
// ...
}
If your command is overriding initialize
method too, then you should call initializeMutex
method by yourself:
class Foo extends Command
{
use WithoutOverlapping;
protected function initialize(InputInterface $input, OutputInterface $output)
{
$this->initializeMutex();
$this->bar = $this->argument('bar');
$this->baz = $this->argument('baz');
}
// ...
}
If you're using some other cool illuminated/console-%
packages, well, then you can find yourself getting "traits conflict".
For example, if you're trying to build loggable command, which is protected against overlapping:
class Foo extends Command
{
use Loggable;
use WithoutOverlapping;
// ...
}
You'll get fatal error, the "traits conflict", because both of these traits are overriding initialize
method:
If two traits insert a method with the same name, a fatal error is produced, if the conflict is not explicitly resolved.
But don't worry, solution is very simple. Just override initialize
method by yourself, and initialize traits in required order:
class Foo extends Command
{
use Loggable;
use WithoutOverlapping;
protected function initialize(InputInterface $input, OutputInterface $output)
{
$this->initializeMutex();
$this->initializeLogging();
}
// ...
}