PHPackages                             darkghosthunter/laralocker - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Queues &amp; Workers](/categories/queues)
4. /
5. darkghosthunter/laralocker

AbandonedArchivedLibrary[Queues &amp; Workers](/categories/queues)

darkghosthunter/laralocker
==========================

Avoid race condition in your Queue Jobs, Listeners and Notifications

v2.0.0(5y ago)454.0k6MITPHPPHP &gt;=7.4

Since Aug 7Pushed 4y ago3 watchersCompare

[ Source](https://github.com/DarkGhostHunter/Laralocker)[ Packagist](https://packagist.org/packages/darkghosthunter/laralocker)[ Docs](https://github.com/darkghosthunter/laralocker)[ Fund](https://paypal.me/darkghosthunter)[ Fund](https://ko-fi.com/DarkGhostHunter)[ RSS](/packages/darkghosthunter-laralocker/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (4)Dependencies (7)Versions (7)Used By (0)

The problematic of this package is resolved using [Unique Jobs](https://laravel.com/docs/queues#unique-jobs).

This package is no longer maintained.

---

Laralocker
==========

[](#laralocker)

[![John Doyle - Unsplash (UL) #dAW17ADBZEM](https://camo.githubusercontent.com/1bc7c04ef180a28165d7ab41371e22efe120ca6b1b8ac4f504393e5c48d9c059/68747470733a2f2f696d616765732e756e73706c6173682e636f6d2f70686f746f2d313534333835333830312d3865363237623565366562663f69786c69623d72622d312e322e31266175746f3d666f726d6174266669743d63726f7026773d3132383026683d34303026713d3830)](https://camo.githubusercontent.com/1bc7c04ef180a28165d7ab41371e22efe120ca6b1b8ac4f504393e5c48d9c059/68747470733a2f2f696d616765732e756e73706c6173682e636f6d2f70686f746f2d313534333835333830312d3865363237623565366562663f69786c69623d72622d312e322e31266175746f3d666f726d6174266669743d63726f7026773d3132383026683d34303026713d3830)

[![Latest Stable Version](https://camo.githubusercontent.com/2150dc7989b47cd9a4beb462f7df2bdb74d3de40a005c5511cb84434be8904c2/68747470733a2f2f706f7365722e707567782e6f72672f6461726b67686f737468756e7465722f6c6172616c6f636b65722f762f737461626c65)](https://packagist.org/packages/darkghosthunter/laralocker) [![License](https://camo.githubusercontent.com/c34465497c6f7a49cf281c614f441edb9152d25dd1d829d73043e6674b6592f5/68747470733a2f2f706f7365722e707567782e6f72672f6461726b67686f737468756e7465722f6c6172616c6f636b65722f6c6963656e7365)](https://packagist.org/packages/darkghosthunter/laralocker)[![](https://camo.githubusercontent.com/bf708c53011a1af32b99a0c3ca98f1f2901e83f1deddbf02ab5168a18ab72cfa/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f6461726b67686f737468756e7465722f6c6172616c6f636b65722e737667)](https://camo.githubusercontent.com/bf708c53011a1af32b99a0c3ca98f1f2901e83f1deddbf02ab5168a18ab72cfa/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f6461726b67686f737468756e7465722f6c6172616c6f636b65722e737667) [![](https://github.com/DarkGhostHunter/Laralocker/workflows/PHP%20Composer/badge.svg)](https://github.com/DarkGhostHunter/Laralocker/workflows/PHP%20Composer/badge.svg) [![Coverage Status](https://camo.githubusercontent.com/508c246a865e7fd044cdf4d3bdbe8edf9125f1d39006ff18ce743ca9c45b4289/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6769746875622f4461726b47686f737448756e7465722f4c6172616c6f636b65722f62616467652e7376673f6272616e63683d6d6173746572)](https://coveralls.io/github/DarkGhostHunter/Laralocker?branch=master) [![Maintainability](https://camo.githubusercontent.com/3203d022df61d6496cd0a57885ad82a603a22022908d172a1af8c34a541df0b9/68747470733a2f2f6170692e636f6465636c696d6174652e636f6d2f76312f6261646765732f62363062336634633066373166373834313136332f6d61696e7461696e6162696c697479)](https://codeclimate.com/github/DarkGhostHunter/Laralocker/maintainability)

Avoid [race conditions](https://en.wikipedia.org/wiki/Race_condition) in your Jobs, Listeners and Notifications with this simple locker reservation system.

Requisites
----------

[](#requisites)

- PHP 7.4, 8.0 or later
- Laravel 7.x, 8.x or later

Installation
------------

[](#installation)

Fire up composer:

```
composer require darkghosthunter/laralocker
```

When you should use Laralocker?
-------------------------------

[](#when-you-should-use-laralocker)

Anything that has **[race conditions](https://en.wikipedia.org/wiki/Race_condition)**.

For example, let's say we need to create a sequential serial key for a sold Ticket, like `AAAA-BBBB-CCCC`. This is done by a Job pushed to the queue. This introduces three problems:

- If two or more jobs started at the same time, these would check the last sold also at the same time, and **save the next Ticket with the same serial key**.
- If we use [Pessimistic Locking](https://laravel.com/docs/8.x/queries#pessimistic-locking) in our queue, we can be victims of [deadlocks](https://en.wikipedia.org/wiki/Deadlock) (a locked row cannot be modified *forever*).
- If we have one Queue Worker, it will only process one Ticket at a time. When a flood of users buy 1,000 tickets in one minute, a single Queue Worker will take its sweet time to process all. The Concert starts in five minutes, hope your CPU is a top of the line AMD EPYC!

Using this package, all Tickets can be dispatched concurrently without fear of collisions, just by reserving a *slot* (like and ID) for processing.

How it works
------------

[](#how-it-works)

This package allows your Job, Listener or Notification to be `Lockable`. With just adding three lines of code, the Job will *look ahead* for a free "slot", and reserve it.

> For sake of simplicity, I will treat Notifications and Listeners as a Jobs, since all of these can be pushed to the Queue.

Once the Job finishes processing, it will release the "slot", and mark that slot as the starting point for the next Jobs, so they don't look ahead from the very beginning.

This is useful when your Jobs needs sequential data: Serial keys, result of calculations, timestamps, you name it.

Usage
-----

[](#usage)

1. Add the `Lockable` interface to your Job, Notification or Listener.
2. Add the `HandlesLock` trait.
3. Add the `LockerJobMiddleware` middleware.
4. Implement the `startFrom()` and `next()`.

> Job Middleware only runs when the Job implements the `ShouldQueue` interface. If you need your job to run in the same process without bypassing the middleware, use `dispatch_sync()` or [`MyJob::dispatchSync()`](https://laravel.com/docs/8.x/queues#synchronous-dispatching).

Example
-------

[](#example)

Here is a full example of a simple Listener that handles Serial Keys when a Ticket is sold for a given Concert to a given User. Once done, the user will be able to print his ticket and use it on the Concert premises to enter.

```
