LaravelPackages.net
Acme Inc.
Toggle sidebar
illuminated/console-mutex

Mutex for Laravel Console Commands.

977.240
147
12.0.0
About illuminated/console-mutex

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

Buy me a coffee

StyleCI Build Status Coverage Status

Packagist Version Packagist Stars Packagist Downloads Packagist License

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.* |

Laravel Console Mutex - Demo

Table of contents

Usage

  1. Install the package via Composer:

    composer require illuminated/console-mutex
    
  2. 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();
    }

    // ...
}

Sponsors

Laravel Idea
Material Theme UI Plugin

License

Laravel Console Mutex is open-sourced software licensed under the MIT license.

Buy me a coffee 

Star History Chart