illuminated/console-mutex is a Laravel package for mutex for laravel console commands..
It currently has 147 GitHub stars and 977.240 downloads on Packagist (latest version 12.0.0).
Install it with composer require illuminated/console-mutex.
Discover more Laravel packages by illuminated
or browse all Laravel packages to compare alternatives.
Last updated

Mutex for Laravel Console Commands.
| Laravel | Console Mutex | |---------|--------------------------------------------------------------------------| | 12.x | 12.x | | 11.x | 11.x | | 10.x | 10.x | | 9.x | 9.x | | 8.x | 8.x | | 7.x | 7.x | | 6.x | 6.x | | 5.8.* | 5.8.* | | 5.7.* | 5.7.* | | 5.6.* | 5.6.* | | 5.5.* | 5.5.* | | 5.4.* | 5.4.* | | 5.3.* | 5.3.* | | 5.2.* | 5.2.* | | 5.1.* | 5.1.* |

Install the package via Composer:
composer require illuminated/console-mutex
Use Illuminated\Console\WithoutOverlapping trait:
use Illuminated\Console\WithoutOverlapping;
class ExampleCommand extends Command
{
use WithoutOverlapping;
// ...
}
Mutex can prevent overlapping by using various strategies:
file (default)mysqlredismemcachedThe default file strategy is acceptable for small applications, which are deployed on a single server.
If your application is more complex and deployed on several nodes, you should consider using another mutex strategy.
You can change strategy by using the $mutexStrategy field:
class ExampleCommand extends Command
{
use WithoutOverlapping;
protected string $mutexStrategy = 'mysql';
// ...
}
Or by using the setMutexStrategy() method:
class ExampleCommand extends Command
{
use WithoutOverlapping;
public function __construct()
{
parent::__construct();
$this->setMutexStrategy('mysql');
}
// ...
}
By default, if mutex sees that the command is already running, it will immediately quit. You can change that behavior by setting a timeout in which mutex can wait for another running command to finish its execution.
You can set the timeout by specifying the $mutexTimeout field:
class ExampleCommand extends Command
{
use WithoutOverlapping;
// In milliseconds
protected ?int $mutexTimeout = 3000;
// ...
}
Or by using the setMutexTimeout() method:
class ExampleCommand extends Command
{
use WithoutOverlapping;
public function __construct()
{
parent::__construct();
// In milliseconds
$this->setMutexTimeout(3000);
}
// ...
}
Here's how the $mutexTimeout field is treated:
0 - no waiting (default);{int} - wait for the given number of milliseconds;null - wait for the running command to finish its execution;Sometimes it might be useful to have a shared mutex for multiple commands. You can easily achieve that by setting the same mutex name for all of those commands.
You should use the getMutexName() method for that:
class ExampleCommand extends Command
{
use WithoutOverlapping;
public function getMutexName()
{
return 'shared-for-command1-and-command2';
}
// ...
}
If you're using the file strategy, mutex files would be stored in the storage/app folder.
You can change that by overriding the getMutexFileStorage() method:
class ExampleCommand extends Command
{
use WithoutOverlapping;
public function getMutexFileStorage()
{
return storage_path('my/custom/path');
}
// ...
}
WithoutOverlapping trait overrides the initialize() method:
trait WithoutOverlapping
{
protected function initialize(InputInterface $input, OutputInterface $output)
{
$this->initializeMutex();
parent::initialize($input, $output);
}
// ...
}
If your command overrides the initialize() method too, you have to call the initializeMutex() method by yourself:
class ExampleCommand extends Command
{
use WithoutOverlapping;
protected function initialize(InputInterface $input, OutputInterface $output)
{
// You have to call it first
$this->initializeMutex();
// Then goes your custom code
$this->foo = $this->argument('foo');
$this->bar = $this->argument('bar');
$this->baz = $this->argument('baz');
}
// ...
}
If you're using another illuminated/console-% package, you'll get the "traits conflict" error.
For example, if you're building a loggable command, which doesn't allow overlapping:
class ExampleCommand extends Command
{
use Loggable;
use WithoutOverlapping;
// ...
}
You'll get the traits conflict, because both of those traits are overriding the initialize() method:
If two traits insert a method with the same name, a fatal error is produced, if the conflict is not explicitly resolved.
To fix that - override the initialize() method and resolve the conflict:
class ExampleCommand extends Command
{
use Loggable;
use WithoutOverlapping;
protected function initialize(InputInterface $input, OutputInterface $output)
{
// Initialize conflicting traits
$this->initializeMutex();
$this->initializeLogging();
}
// ...
}
Laravel Console Mutex is open-sourced software licensed under the MIT license.