Mutex for Laravel Console Commands.

Overview

Mutex for Laravel Console Commands

Laravel Console Mutex

Become a Patron

StyleCI Build Status Coverage Status

Packagist Version Packagist Stars Packagist Downloads Packagist License

Mutex for Laravel Console Commands.

Laravel Console Mutex
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 $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 $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

License

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

Support on Patreon

Comments
  • Mutex file is not deleted

    Mutex file is not deleted

    I installed your package and when using the file mutex option, after the command is finished the mutex file is still there... When I try to rerun the command it will fail with error:

    [RuntimeException]
      Command is running now!
    

    I used this config setting:

    protected $mutexStrategy = 'file';
    
    public function getMutexName()
    {
        return 'icmutex-test';
    }
    
    opened by it-can 9
  • Laravel 9.x Compatibility

    Laravel 9.x Compatibility

    This is an automated pull request from Shift to update your package code and dependencies to be compatible with Laravel 9.x.

    Before merging, you need to:

    • Checkout the l9-compatibility branch
    • Review all comments for additional changes
    • Thoroughly test your package

    If you do find an issue, please report it by commenting on this PR to help improve future automation.

    opened by laravel-shift 5
  • Command with different params is not working

    Command with different params is not working

    Hi,

    First of all great work. For some reasons Laravel's withoutOverlapping() method didn't work for me because I was seeing same commands overlapping so I opt in to use your package. I think Laravel team should use your package!

    I have a command which accepts different arguments i.e. php artisan --action=cleanup or php artisan --action=check-db --table=xyz

    Both commands are doing different nature of tasks so your package shouldn't throw error. Is there any chance you can add lock based on the params passed to command?

    Also, it would be great if you can add an option to show a warning message instead of throwing exception: Command is running now! A variable like this in the class will work fine $this->useWarning = true; or have a setting?

    opened by moazam1 5
  • Not working in tests

    Not working in tests

    Versions:

    • Package Version: 7.0.0

    • PHP Version: 7.4

    Description:

    if you want to run a command in test more than 1 time you get an error than the command is running now

    Steps to reproduce:

    <?php
    class YourCommandTest extends TestCase
    {
    
        public function testExample()
        {
            $this->artisan('command', ['param' => 'value']);
        }
    
        public function test2Example()
        {
            $this->artisan('command', ['param' => 'value']); // throw exception
        }
    }
    
    opened by cezar62882 4
  • check laravel database config and grab redis driver

    check laravel database config and grab redis driver

    As it is possible to have the php-redis installed there is the need to distinguish which driver should be used. This is possible by reading the database.redis.client property from conf/database.php.

    opened by olafnorge 4
  • New MySQLPDOLock class on NinjaMutex and MySQL driver with options

    New MySQLPDOLock class on NinjaMutex and MySQL driver with options

    This PR allows to use the mysql strategy and set options with the PDO driver.

    It was motivated by the need of connecting to a MySQL/MariaDB server with the SSL/TLS option required. If that option is rightly configured in your Laravel's database config this patch uses the database.connections.mysql.options setup transparently.

    NinjaMutex master branch is required to pass the options parameter. Last release of arvenil/mutex at this PR moment is 0.6 so that composer dependency is dev-master#82cbb2c (Feb 1, 2021). If a new release of NinjaMutex is published it should be set on this composer.json.

    opened by rafacouto 3
  • Mutex redis always throws 'Command is running now!' after force stop

    Mutex redis always throws 'Command is running now!' after force stop

    Versions:

    • Package Version: 5.8.*
    • PHP Version: 7.4.3
    • Redis package "predis/predis": "^1.1"

    Description:

    When using redis strategy $this->setMutexStrategy('redis'); running a command through console and force stopping, cannot run the command again. It always says that the command is running and never clears.

    This does not happen with file strategy.

    Expected:

    After force cancel It should behave same as file strategy. Be cleared after some time

    Actual:

    Always returns 'Command is running now!' after force stop (CTRL+C).

    opened by elygiux 3
  • Suppress RuntimeException?

    Suppress RuntimeException?

    To prevent overlapping I'm using your package that basically runs a command in a loop. This is all working fine, only the log is being flood with RuntimeException(code: 0): Command is running now!... Is it possible to log a (debug) message instead of a full exception? Do you maybe have a better idea? :)

    Thanks for your package!

    opened by francoism90 3
  • added Illuminated\Console\Mutex\Exceptions\RuntimeException

    added Illuminated\Console\Mutex\Exceptions\RuntimeException

    I had to create an exception class specifically to this library, so I can ignore these exceptions in Laravel\Lumen\Exceptions\Handler. However, In order to add the exception class, I also had to modify the namespace the library from Illuminated\Console to Illuminated\Console\Mutex, so it wont conflict with other libraries.

    • changed namespace to Illuminated\Console\Mutex
    • added RuntimeException
    opened by aporat 3
  • save temporary variable to be allowed release mutex manually.

    save temporary variable to be allowed release mutex manually.

    I've meet with problem when cover console command with WithoutOverlapping using unit-test. PHPUnit don't release default mutex before all tests end. So I suggest to make possible release mutext by customer in the end of console command. To allow batch of unit-tests pass

    opened by alexbleon 2
  • Issue with PHPUnit testing and mutex not released

    Issue with PHPUnit testing and mutex not released

    Versions:

    • Package Version: 8.1.0
    • PHP Version: 8.0

    Description:

    Everything is working fine when I use the package in real conditions.

    However, I can't make tests on commands that are implementing the WithoutOverlapping trait: the first test is OK but all other tests are throwing the Illuminated\Console\MutexRuntimeException: Command is running now! error.

    I verified by adding a dd('test') in the releaseMutexLock from the NinjaMutex\Lock\FlockLock (default file strategy is set with no timeout) and 4 tests are executed before the mutex is released.

    Is there a way to force the mutex to be released after each test ?

    Steps to reproduce:

    Implement a command and write several tests in a same test class, the mutex will not be released between each test.

    Expected:

    The mutex should be released right after the command has finished.

    Actual:

    The mutex is not released right after the command has finished.

    opened by Okipa 1
Releases(9.2.0)
Owner
Dmitry Ivanov
Software Engineer with 15 years of experience in Web Development who successfully works remotely since 2010.
Dmitry Ivanov
A simple laravel package to validate console commands arguments and options.

Command Validator A simple laravel package to validate console commands arguments and options. Installation Require/Install the package using composer

Touhidur Rahman 20 Jan 20, 2022
A wrapper package to run mysqldump from laravel console commands.

A wrapper package to run mysqldump from laravel console commands.

Yada Khov 24 Jun 24, 2022
In-browser console for Laravel PHP framework.

Laravel 4 Console In-browser console for Laravel 4 PHP framework. This bundle executes your code within ConsoleController@postExecute context, and dis

null 172 Dec 30, 2022
📝 Artisan Menu - Use Artisan via an elegant console GUI

?? Artisan Menu Use Artisan via an elegant console GUI Features Run built-in and custom Artisan commands from a console GUI Prompts to enter required

Jordan Hall 149 Dec 29, 2022
This package provides a console command to convert dynamic JS/CSS to static JS/CSS assets.

Laravel Nova Search This package provides a console command to convert dynamic JS/CSS to static JS/CSS assets. Requirements laravel-mix v6.0+ php 7.3+

Akki Khare 3 Jul 19, 2022
📝 Artisan Menu - Use Artisan via an elegant console GUI

?? Artisan Menu Use Artisan via an elegant console GUI Features Run built-in and custom Artisan commands from a console GUI Prompts to enter required

Jordan Hall 148 Nov 29, 2022
A package for Laravel to perform basic git commands on locally integrated packages.

A package for Laravel to perform basic git commands on locally integrated development packages. If working within multiple local development packages or repositories at once this package is meant to ease the burden of navigating to each individual repository to perform basic git commands.

null 3 Jul 26, 2022
Package for Laravel that gives artisan commands to setup and edit environment files.

Setup and work with .env files in Laravel from the command line NOTE: This doesn't work with Laravel 5 since .env files were changed. This is for Lara

Matt Brunt 6 Dec 17, 2022
The Missing Laravel Commands

Made with ❤️ by SecTheater Foundation Artify CheatSheet will be availble soon Laravel is a great framework and it provides us the ability to create ou

Security Theater 91 Oct 13, 2022
A bookmarkable, searchable cheatsheet for all of Laravel's default Artisan commands.

artisan.page A bookmarkable, searchable cheatsheet for all of Laravel's default Artisan commands. Generation The generation of the manifest files is d

James Brooks 284 Dec 25, 2022
A package for more Laravel commands.

Lara-Commands A package for more Laravel commands. Installation This package can be installed via Composer: composer require nimaw/lara-commands --dev

Nima 7 Jan 9, 2022
Laravel API architecture builder based on artisan commands.

??‍?? API-Formula Laravel API architecture builder based on artisan commands. This package provides a nice and fluent way to generate combined control

Krševan Lisica 1 Jan 16, 2022
This Laravel Nova tool lets you run artisan and bash commands directly from Nova 4 or higher.

Laravel Nova tool for running Artisan & Shell commands. This Nova tool lets you run artisan and bash commands directly from nova. This is an extended

Artem Stepanenko 17 Dec 15, 2022
Execute Laravel Artisan commands via REST APIs and HTTP requests safely.

Artisan Api There might be some times you wanted to execute an Artisan command, but you did not have access to shell or SSH. Here we brought REST API

Alireza 11 Sep 7, 2022
A package that makes it easy to have the `artisan make:` commands open the newly created file in your editor of choice.

Open On Make A package that makes it easy to have the artisan make: commands open the newly created file in your editor of choice. Installation compos

Andrew Huggins 94 Nov 22, 2022
List of 77 languages for Laravel Framework 4, 5, 6, 7 and 8, Laravel Jetstream , Laravel Fortify, Laravel Breeze, Laravel Cashier, Laravel Nova and Laravel Spark.

Laravel Lang In this repository, you can find the lang files for the Laravel Framework 4/5/6/7/8, Laravel Jetstream , Laravel Fortify, Laravel Cashier

Laravel Lang 6.9k Jan 2, 2023
⚡ Laravel Charts — Build charts using laravel. The laravel adapter for Chartisan.

What is laravel charts? Charts is a Laravel library used to create Charts using Chartisan. Chartisan does already have a PHP adapter. However, this li

Erik C. Forés 31 Dec 18, 2022
Laravel Kickstart is a Laravel starter configuration that helps you build Laravel websites faster.

Laravel Kickstart What is Laravel Kickstart? Laravel Kickstart is a Laravel starter configuration that helps you build Laravel websites faster. It com

Sam Rapaport 46 Oct 1, 2022
Laravel User Activity Log - a package for Laravel 8.x that provides easy to use features to log the activities of the users of your Laravel app

Laravel User Activity Log - a package for Laravel 8.x that provides easy to use features to log the activities of the users of your Laravel app

null 9 Dec 14, 2022