olafnorge / console-mutex
Prevents overlapping for Laravel console commands.
Requires
- php: >=5.5.9
- arvenil/ninja-mutex: ^0.6
- illuminate/console: 5.1.*|5.2.*|5.3.*|5.4.*
- illuminate/support: 5.1.*|5.2.*|5.3.*|5.4.*
Requires (Dev)
- ext-pdo_mysql: *
- ext-redis: *
- illuminated/testing-tools: ^0.6
- mockery/mockery: ^0.9
- orchestra/testbench: ^3.1
- phpunit/phpunit: ^5.0
- predis/predis: ^1.1
This package is auto-updated.
Last update: 2020-05-30 09:33:13 UTC
README
Prevents overlapping for Laravel console commands.
Table of contents
Requirements
PHP >=5.5.9
Laravel >=5.1
Usage
-
Install package through
composer
:composer require olafnorge/console-mutex
-
Use
olafnorge\Console\WithoutOverlapping
trait:use olafnorge\Console\WithoutOverlapping; class ExampleCommand extends Command { use WithoutOverlapping; // ... }
Strategies
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 ExampleCommand extends Command { use WithoutOverlapping; protected $mutexStrategy = 'mysql'; // ... }
Or by using setMutexStrategy
method:
class ExampleCommand extends Command { use WithoutOverlapping; public function __construct() { parent::__construct(); $this->setMutexStrategy('mysql'); } // ... }
Advanced
Set custom timeout
By default mutex is checking for a running command, and if it finds such, it just exits. However, you can manually set timeout for a mutex, so it can wait for another command to finish it's execution, instead of just quitting immediately.
You can change mutex timeout by specifying $mutexTimeout
field:
class ExampleCommand extends Command { use WithoutOverlapping; protected $mutexTimeout = 3000; // milliseconds // ... }
Or by using setMutexTimeout
method:
class ExampleCommand extends Command { use WithoutOverlapping; public function __construct() { parent::__construct(); $this->setMutexTimeout(3000); // milliseconds } // ... }
There are three possible options for $mutexTimeout
field:
0
- check without waiting (default);{milliseconds}
- check, and wait for a maximum of milliseconds specified;null
- wait, till running command finish it's execution;
Handle several commands
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 ExampleCommand extends Command { use WithoutOverlapping; public function getMutexName() { return "icmutex-for-command1-and-command2"; } // ... }
Troubleshooting
Trait included, but nothing happens?
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 ExampleCommand extends Command { use WithoutOverlapping; protected function initialize(InputInterface $input, OutputInterface $output) { $this->initializeMutex(); $this->foo = $this->argument('foo'); $this->bar = $this->argument('bar'); $this->baz = $this->argument('baz'); } // ... }
Several traits conflict?
If you're using some other cool olafnorge/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 ExampleCommand 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. Override initialize
method by yourself, and initialize traits in required order:
class ExampleCommand extends Command { use Loggable; use WithoutOverlapping; protected function initialize(InputInterface $input, OutputInterface $output) { $this->initializeMutex(); $this->initializeLogging(); } // ... }