{"id":15634531,"url":"https://github.com/dmitry-ivanov/laravel-console-mutex","last_synced_at":"2025-05-15T12:07:27.924Z","repository":{"id":8735316,"uuid":"59570052","full_name":"dmitry-ivanov/laravel-console-mutex","owner":"dmitry-ivanov","description":"Mutex for Laravel Console Commands.","archived":false,"fork":false,"pushed_at":"2025-03-06T15:38:35.000Z","size":2323,"stargazers_count":141,"open_issues_count":0,"forks_count":31,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-05-13T21:12:06.561Z","etag":null,"topics":["command","console","laravel","laravel-package","locker","mutex","mutex-lock","no-overlapping","semaphore"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dmitry-ivanov.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-05-24T12:11:51.000Z","updated_at":"2025-05-04T14:12:02.000Z","dependencies_parsed_at":"2024-06-18T13:58:29.979Z","dependency_job_id":"ed8f385d-a361-4f8a-a552-fcc64c065baa","html_url":"https://github.com/dmitry-ivanov/laravel-console-mutex","commit_stats":{"total_commits":395,"total_committers":7,"mean_commits":56.42857142857143,"dds":"0.017721518987341756","last_synced_commit":"0e3f65ebe17505f7a3f38752ac8449974c060188"},"previous_names":[],"tags_count":84,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmitry-ivanov%2Flaravel-console-mutex","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmitry-ivanov%2Flaravel-console-mutex/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmitry-ivanov%2Flaravel-console-mutex/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmitry-ivanov%2Flaravel-console-mutex/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dmitry-ivanov","download_url":"https://codeload.github.com/dmitry-ivanov/laravel-console-mutex/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254337608,"owners_count":22054254,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["command","console","laravel","laravel-package","locker","mutex","mutex-lock","no-overlapping","semaphore"],"created_at":"2024-10-03T10:53:53.854Z","updated_at":"2025-05-15T12:07:22.906Z","avatar_url":"https://github.com/dmitry-ivanov.png","language":"PHP","funding_links":["https://buymeacoffee.com/dmitry.ivanov","https://buymeacoffee.com/dmitry.ivanov)"],"categories":[],"sub_categories":[],"readme":"![Mutex for Laravel Console Commands](art/1380x575-optimized.jpg)\n\n# Laravel Console Mutex\n\n[\u003cimg src=\"https://user-images.githubusercontent.com/1286821/181085373-12eee197-187a-4438-90fe-571ac6d68900.png\" alt=\"Buy me a coffee\" width=\"200\" /\u003e](https://buymeacoffee.com/dmitry.ivanov)\n\n[![StyleCI](https://github.styleci.io/repos/59570052/shield?branch=master\u0026style=flat)](https://github.styleci.io/repos/59570052?branch=master)\n[![Build Status](https://img.shields.io/github/actions/workflow/status/dmitry-ivanov/laravel-console-mutex/tests.yml?branch=master)](https://github.com/dmitry-ivanov/laravel-console-mutex/actions?query=workflow%3Atests+branch%3Amaster)\n[![Coverage Status](https://img.shields.io/codecov/c/github/dmitry-ivanov/laravel-console-mutex/master)](https://app.codecov.io/gh/dmitry-ivanov/laravel-console-mutex/tree/master)\n\n![Packagist Version](https://img.shields.io/packagist/v/illuminated/console-mutex)\n![Packagist Stars](https://img.shields.io/packagist/stars/illuminated/console-mutex)\n![Packagist Downloads](https://img.shields.io/packagist/dt/illuminated/console-mutex)\n![Packagist License](https://img.shields.io/packagist/l/illuminated/console-mutex)\n\nMutex for Laravel Console Commands.\n\n| Laravel | Console Mutex                                                            |\n|---------|--------------------------------------------------------------------------|\n| 12.x    | [12.x](https://github.com/dmitry-ivanov/laravel-console-mutex/tree/12.x) |\n| 11.x    | [11.x](https://github.com/dmitry-ivanov/laravel-console-mutex/tree/11.x) |\n| 10.x    | [10.x](https://github.com/dmitry-ivanov/laravel-console-mutex/tree/10.x) |\n| 9.x     | [9.x](https://github.com/dmitry-ivanov/laravel-console-mutex/tree/9.x)   |\n| 8.x     | [8.x](https://github.com/dmitry-ivanov/laravel-console-mutex/tree/8.x)   |\n| 7.x     | [7.x](https://github.com/dmitry-ivanov/laravel-console-mutex/tree/7.x)   |\n| 6.x     | [6.x](https://github.com/dmitry-ivanov/laravel-console-mutex/tree/6.x)   |\n| 5.8.*   | [5.8.*](https://github.com/dmitry-ivanov/laravel-console-mutex/tree/5.8) |\n| 5.7.*   | [5.7.*](https://github.com/dmitry-ivanov/laravel-console-mutex/tree/5.7) |\n| 5.6.*   | [5.6.*](https://github.com/dmitry-ivanov/laravel-console-mutex/tree/5.6) |\n| 5.5.*   | [5.5.*](https://github.com/dmitry-ivanov/laravel-console-mutex/tree/5.5) |\n| 5.4.*   | [5.4.*](https://github.com/dmitry-ivanov/laravel-console-mutex/tree/5.4) |\n| 5.3.*   | [5.3.*](https://github.com/dmitry-ivanov/laravel-console-mutex/tree/5.3) |\n| 5.2.*   | [5.2.*](https://github.com/dmitry-ivanov/laravel-console-mutex/tree/5.2) |\n| 5.1.*   | [5.1.*](https://github.com/dmitry-ivanov/laravel-console-mutex/tree/5.1) |\n\n![Laravel Console Mutex - Demo](doc/img/demo.gif)\n\n## Table of contents\n\n- [Usage](#usage)\n- [Strategies](#strategies)\n- [Advanced](#advanced)\n  - [Set custom timeout](#set-custom-timeout)\n  - [Handle multiple commands](#handle-multiple-commands)\n  - [Set custom storage folder](#set-custom-storage-folder)\n- [Troubleshooting](#troubleshooting)\n  - [Trait included, but nothing happens?](#trait-included-but-nothing-happens)\n  - [Several traits conflict?](#several-traits-conflict)\n- [Sponsors](#sponsors)\n- [License](#license)\n\n## Usage\n\n1. Install the package via Composer:\n\n    ```shell script\n    composer require illuminated/console-mutex\n    ```\n\n2. Use `Illuminated\\Console\\WithoutOverlapping` trait:\n\n    ```php\n    use Illuminated\\Console\\WithoutOverlapping;\n\n    class ExampleCommand extends Command\n    {\n        use WithoutOverlapping;\n\n        // ...\n    }\n    ```\n\n## Strategies\n\nMutex can prevent overlapping by using various strategies:\n\n- `file` (default)\n- `mysql`\n- `redis`\n- `memcached`\n\nThe default `file` strategy is acceptable for small applications, which are deployed on a single server.\nIf your application is more complex and deployed on several nodes, you should consider using another mutex strategy.\n\nYou can change strategy by using the `$mutexStrategy` field:\n\n```php\nclass ExampleCommand extends Command\n{\n    use WithoutOverlapping;\n\n    protected string $mutexStrategy = 'mysql';\n\n    // ...\n}\n```\n\nOr by using the `setMutexStrategy()` method:\n\n```php\nclass ExampleCommand extends Command\n{\n    use WithoutOverlapping;\n\n    public function __construct()\n    {\n        parent::__construct();\n\n        $this-\u003esetMutexStrategy('mysql');\n    }\n\n    // ...\n}\n```\n\n## Advanced\n\n### Set custom timeout\n\nBy default, if mutex sees that the command is already running, it will immediately quit.\nYou can change that behavior by setting a timeout in which mutex can wait for another running command to finish its execution.\n\nYou can set the timeout by specifying the `$mutexTimeout` field:\n\n```php\nclass ExampleCommand extends Command\n{\n    use WithoutOverlapping;\n\n    // In milliseconds\n    protected ?int $mutexTimeout = 3000;\n\n    // ...\n}\n```\n\nOr by using the `setMutexTimeout()` method:\n\n```php\nclass ExampleCommand extends Command\n{\n    use WithoutOverlapping;\n\n    public function __construct()\n    {\n        parent::__construct();\n\n        // In milliseconds\n        $this-\u003esetMutexTimeout(3000);\n    }\n\n    // ...\n}\n```\n\nHere's how the `$mutexTimeout` field is treated:\n\n- `0` - no waiting (default);\n- `{int}` - wait for the given number of milliseconds;\n- `null` - wait for the running command to finish its execution;\n\n### Handle multiple commands\n\nSometimes it might be useful to have a shared mutex for multiple commands.\nYou can easily achieve that by setting the same mutex name for all of those commands.\n\nYou should use the `getMutexName()` method for that:\n\n```php\nclass ExampleCommand extends Command\n{\n    use WithoutOverlapping;\n\n    public function getMutexName()\n    {\n        return 'shared-for-command1-and-command2';\n    }\n\n    // ...\n}\n```\n\n### Set custom storage folder\n\nIf you're using the `file` strategy, mutex files would be stored in the `storage/app` folder.\n\nYou can change that by overriding the `getMutexFileStorage()` method:\n\n```php\nclass ExampleCommand extends Command\n{\n    use WithoutOverlapping;\n\n    public function getMutexFileStorage()\n    {\n        return storage_path('my/custom/path');\n    }\n\n    // ...\n}\n```\n\n## Troubleshooting\n\n### Trait included, but nothing happens?\n\n`WithoutOverlapping` trait overrides the `initialize()` method:\n\n```php\ntrait WithoutOverlapping\n{\n    protected function initialize(InputInterface $input, OutputInterface $output)\n    {\n        $this-\u003einitializeMutex();\n\n        parent::initialize($input, $output);\n    }\n\n    // ...\n}\n```\n\nIf your command overrides the `initialize()` method too, you have to call the `initializeMutex()` method by yourself:\n\n```php\nclass ExampleCommand extends Command\n{\n    use WithoutOverlapping;\n\n    protected function initialize(InputInterface $input, OutputInterface $output)\n    {\n        // You have to call it first\n        $this-\u003einitializeMutex();\n\n        // Then goes your custom code\n        $this-\u003efoo = $this-\u003eargument('foo');\n        $this-\u003ebar = $this-\u003eargument('bar');\n        $this-\u003ebaz = $this-\u003eargument('baz');\n    }\n\n    // ...\n}\n```\n\n### Several traits conflict?\n\nIf you're using another `illuminated/console-%` package, you'll get the \"traits conflict\" error.\n\nFor example, if you're building a [loggable command](https://github.com/dmitry-ivanov/laravel-console-logger), which doesn't allow overlapping:\n\n```php\nclass ExampleCommand extends Command\n{\n    use Loggable;\n    use WithoutOverlapping;\n\n    // ...\n}\n```\n\nYou'll get the traits conflict, because both of those traits are overriding the `initialize()` method:\n\u003e If two traits insert a method with the same name, a fatal error is produced, if the conflict is not explicitly resolved.\n\nTo fix that - override the `initialize()` method and resolve the conflict:\n\n```php\nclass ExampleCommand extends Command\n{\n    use Loggable;\n    use WithoutOverlapping;\n\n    protected function initialize(InputInterface $input, OutputInterface $output)\n    {\n        // Initialize conflicting traits\n        $this-\u003einitializeMutex();\n        $this-\u003einitializeLogging();\n    }\n\n    // ...\n}\n```\n\n## Sponsors\n\n[![Laravel Idea](art/sponsor-laravel-idea.png)](https://laravel-idea.com)\u003cbr\u003e\n[![Material Theme UI Plugin](art/sponsor-material-theme.png)](https://material-theme.com)\u003cbr\u003e\n\n## License\n\nLaravel Console Mutex is open-sourced software licensed under the [MIT license](LICENSE.md).\n\n[\u003cimg src=\"https://user-images.githubusercontent.com/1286821/181085373-12eee197-187a-4438-90fe-571ac6d68900.png\" alt=\"Buy me a coffee\" width=\"200\" /\u003e](https://buymeacoffee.com/dmitry.ivanov)\u0026nbsp;\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdmitry-ivanov%2Flaravel-console-mutex","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdmitry-ivanov%2Flaravel-console-mutex","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdmitry-ivanov%2Flaravel-console-mutex/lists"}