Stars: 131
Forks: 20
Pull Requests: 17
Issues: 17
Watchers: 8
Last Updated: 2023-01-31 19:50:01
Mutex for Laravel Console Commands.
License: MIT License
Languages: PHP
Mutex for Laravel Console Commands.
| Laravel | Console Mutex |
|---|---|
| 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-mutexUse 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.