oriceon / console-mutex
Mutex for Laravel Console Commands. Fork for Laravel 10.x
Requires
- php: ^8.1|^8.2
- arvenil/ninja-mutex: dev-master#82cbb2c
- illuminate/console: ^10.0|^11.0
- illuminate/support: ^10.0|^11.0
- ramsey/collection: ^2.0
Requires (Dev)
- ext-pdo_mysql: *
- ext-redis: *
- mockery/mockery: ^1.4.4
- orchestra/testbench: ^8.0
- phpunit/phpunit: ^9.5.10
- predis/predis: ^2.0
- srd2010/testing-tools: ^10.0
This package is auto-updated.
Last update: 2024-11-14 08:19:04 UTC
README
Laravel Console Mutex
This is a fork from the original Repository to support Laravel v10.x
Mutex for Laravel Console Commands.
Table of contents
Usage
-
Install the package via Composer:
composer require srd2010/console-mutex
-
Use
Illuminated\Console\WithoutOverlapping
trait:use Illuminated\Console\WithoutOverlapping; class ExampleCommand extends Command { use WithoutOverlapping; // ... }
Strategies
Mutex can prevent overlapping by using various strategies:
file
(default)mysql
redis
memcached
The 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'); } // ... }
Advanced
Set custom timeout
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;
Handle multiple commands
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'; } // ... }
Set custom storage folder
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'); } // ... }
Troubleshooting
Trait included, but nothing happens?
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'); } // ... }
Several traits conflict?
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(); } // ... }
Original Sponsors
License
Laravel Console Mutex is open-sourced software licensed under the MIT license.