PHPackages                             remi-san/lock - 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. [Caching](/categories/caching)
4. /
5. remi-san/lock

ActiveLibrary[Caching](/categories/caching)

remi-san/lock
=============

A locking lib

v1.0.2(5y ago)46.8k1MITPHPPHP &gt;=5.5CI failing

Since Sep 1Pushed 5y ago1 watchersCompare

[ Source](https://github.com/remi-san/lock)[ Packagist](https://packagist.org/packages/remi-san/lock)[ RSS](/packages/remi-san-lock/feed)WikiDiscussions master Synced 2mo ago

READMEChangelog (3)Dependencies (5)Versions (4)Used By (0)

Lock
====

[](#lock)

[![Author](https://camo.githubusercontent.com/4488dd05eac93ae677fc802ca3f7ecdf019ffac5386384282044a33dd0858654/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f617574686f722d4052656d6953616e2d626c75652e7376673f7374796c653d666c61742d737175617265)](https://twitter.com/RemiSan)[![Build Status](https://camo.githubusercontent.com/e5b4bf30b115b0ebf2704050f08fcdff7226f64371fb29b173cb0b674960c968/68747470733a2f2f696d672e736869656c64732e696f2f7472617669732f72656d692d73616e2f6c6f636b2f6d61737465722e7376673f7374796c653d666c61742d737175617265)](https://travis-ci.org/remi-san/lock)[![Quality Score](https://camo.githubusercontent.com/9d935f85a1a7b46b7ef96f0eeb9e23b52a07dee53902f2702df91f5d6213a9a9/68747470733a2f2f696d672e736869656c64732e696f2f7363727574696e697a65722f672f72656d692d73616e2f6c6f636b2e7376673f7374796c653d666c61742d737175617265)](https://scrutinizer-ci.com/g/remi-san/lock)[![Software License](https://camo.githubusercontent.com/55c0218c8f8009f06ad4ddae837ddd05301481fcf0dff8e0ed9dadda8780713e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265)](LICENSE)[![Packagist Version](https://camo.githubusercontent.com/de2bc99146f115d6ce08b5d2f18bde040180533e40002106e4ee1ea4713fee86/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f72656d692d73616e2f6c6f636b2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/remi-san/lock)[![Coverage Status](https://camo.githubusercontent.com/9f31c47d17d2d3a00626eb76f689982a59aa8f85be45244c54e4461da29111dc/68747470733a2f2f696d672e736869656c64732e696f2f7363727574696e697a65722f636f7665726167652f672f72656d692d73616e2f6c6f636b2e7376673f7374796c653d666c61742d737175617265)](https://scrutinizer-ci.com/g/remi-san/lock/code-structure)[![SensioLabsInsight](https://camo.githubusercontent.com/7a19d3a393ed9deb688ce17ed26f4b533226a91622a53b246c45124ec6a6c89a/68747470733a2f2f696e73696768742e73656e73696f6c6162732e636f6d2f70726f6a656374732f34356462386362642d373061382d346330392d396238302d3332623531626139326338362f6d696e692e706e67)](https://insight.sensiolabs.com/projects/45db8cbd-70a8-4c09-9b80-32b51ba92c86)

Description
-----------

[](#description)

**`Lock`** is a library aimed at providing a simple and reliable way to lock resources.

Main classes
------------

[](#main-classes)

- `RemiSan\Lock\Locker` which provides an interface containing the following methods:

    - `lock` to lock a resource for a given time (`ttl` - not mandatory), allowing to retry a certain amount of times until success.
    - `isLocked` to check if a resource is still locked.
    - `unlock` to unlock a resource.
- `RemiSan\Lock\Lock` which provides a structure to store information about the lock:

    - `resource` the resource that has been locked
    - `token` a token generated by the `Locker` (using a `RemiSan\Lock\TokenGenerator` implementation) to ensure the requested unlocking resource is the same that the one who's been locked.
    - `validityEndTime` the time (in milliseconds since EPOCH) at which the lock will be automatically released (if a ttl has been defined).

Token Generators
----------------

[](#token-generators)

As the `Locker` will need to generate a unique token to lock the `resource`, a `TokenGenerator` interface has been defined, and 2 implementations are available:

- `RandomTokenGenerator` which will provide a random token.
- `FixedTokenGenerator` which will always provide the token passed in the constructor.

**Examples:**

```
use RemiSan\Lock\TokenGenerator\RandomTokenGenerator;

$tokenGenerator = new RandomTokenGenerator();
echo $tokenGenerator->generateToken(); // 'QcWY1WFoRTC68vTNIkTs5cuLmw9YuY9rwS6IsY0xjzA='
```

```
use RemiSan\Lock\TokenGenerator\FixedTokenGenerator;

$tokenGenerator = new FixedTokenGenerator('my_token');
echo $tokenGenerator->generateToken(); // 'my_token'
```

Quorum
------

[](#quorum)

`Quorum` is used to determinate if enough `LockStores` have written the lock to consider it really locked.

Two implementations are provided:

- `MajorityQuorum` which will state quorum is met if more than half of the stores have written the lock.
- `UnanimousQuorum` which will state quorum is met if all stores have written the lock.

Quorum is only used when dealing with multiple stores.

Usage
-----

[](#usage)

**Create**

You can chose between the Single-Store implementation:

```
use RemiSan\Lock\LockStore\RedisLockStore;
use RemiSan\Lock\Locker\SingleStoreLocker;
use RemiSan\Lock\TokenGenerator\RandomTokenGenerator;
use Symfony\Component\Stopwatch\Stopwatch;

$connection = new \Redis();
$server->connect('127.0.0.1', 6379, 0.1);

$tokenGenerator = new RandomTokenGenerator();
$stopwatch = new Stopwatch();

$redLock = new SingleStoreLocker(
    new RedisLockStore($connection),
    $tokenGenerator,
    $stopwatch
);
```

Or the Multiple-Store implementation:

```
use RemiSan\Lock\LockStore\RedisLockStore;
use RemiSan\Lock\Locker\MultipleStoreLocker;
use RemiSan\Lock\Quorum\MajorityQuorum;
use RemiSan\Lock\TokenGenerator\RandomTokenGenerator;
use Symfony\Component\Stopwatch\Stopwatch;

$connection1 = new \Redis();
$server->connect('127.0.0.1', 6379, 0.1);

$connection2 = new \Redis();
$server->connect('127.0.0.1', 6380, 0.1);

$tokenGenerator = new RandomTokenGenerator();
$quorum = new MajorityQuorum();
$stopwatch = new Stopwatch();

$redLock = new MultipleStoreLocker(
    [ new RedisLockStore($connection1), new RedisLockStore($connection2) ],
    $tokenGenerator,
    $quorum,
    $stopwatch
);
```

**Acquire a lock**

You can acquire a lock on a resource by providing its name, the `ttl`, the retry count and the time (in milliseconds) to wait before retrying.

```
$lock = $locker->lock('my_resource_name', 1000, 3, 100);
```

This example will try to lock the resource `my_resource_name` for 1 second (1000ms) and will retry to acquire it 3 times if it fails the first time (4 in total if all fail), waiting 100ms between each try.

If the lock is acquired, it will return a `Lock` object describing it.

If it failed being acquired, it will throw a `RemiSan\Lock\Exceptions\LockingException`.

*For the Multiple-Store*: The lock will be acquired only if the number of instances that have been able to acquire the lock meet the quorum (the calculation of the `quorum` is made according to the implementation of `Quorum` passed to the `MultipleInstanceLocker`).

**Assert if a lock exists**

You can ask the `Locker` if a resource is still locked.

```
$isLocked = $locker->isLocked('my_resource_name');
```

If the resource is still locked (lock has been acquired and ttl hasn't expired), it will return `true`, it will return `false` otherwise.

*For the Multiple-Store*: If at least one connected instance has the lock, it will consider having the lock.

**Release a lock**

To release a lock you have to provide it to the `Locker`.

```
$locker->unlock($lock);
```

If the lock is still active, it will release it. If it fails but the lock wasn't active anymore, it won't cause any error.

If it fails releasing the lock and the lock is still active, it will throw a `RemiSan\Lock\Exceptions\UnlockingException`.

*For the Multiple-Store*: If at least one connected instance fails releasing the lock while still detaining it, the exception will be thrown.

Redis LockStore
---------------

[](#redis-lockstore)

Based on [Redlock-rb](https://github.com/antirez/redlock-rb) by [Salvatore Sanfilippo](https://github.com/antirez) and [ronnylt/redlock-php](https://github.com/ronnylt/redlock-php).

This library implements the Redis-based distributed lock manager algorithm [described in this Redis article](http://redis.io/topics/distlock).

This lib provides a `RedisLockStore` implementing the `RedLock` mechanism.

**DISCLAIMER**: As stated in the original `antirez` version, this code implements an algorithm which is currently a proposal, it was not formally analyzed. Make sure to understand how it works before using it in your production environments.

Other LockStores
----------------

[](#other-lockstores)

That will come at some point, but it's not there yet.

###  Health Score

31

—

LowBetter than 68% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity23

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity60

Established project with proven stability

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~817 days

Total

3

Last Release

1909d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/9999746240ba052017622ecdce5ac44e6a43db5f38084ff7644691207925c043?d=identicon)[remi-san](/maintainers/remi-san)

---

Top Contributors

[![remi-san](https://avatars.githubusercontent.com/u/5213540?v=4)](https://github.com/remi-san "remi-san (28 commits)")

---

Tags

lockredis

###  Code Quality

TestsPHPUnit

Code StylePHP\_CodeSniffer

### Embed Badge

![Health badge](/badges/remi-san-lock/health.svg)

```
[![Health](https://phpackages.com/badges/remi-san-lock/health.svg)](https://phpackages.com/packages/remi-san-lock)
```

###  Alternatives

[symfony/cache

Provides extended PSR-6, PSR-16 (and tags) implementations

4.2k348.9M2.5k](/packages/symfony-cache)[cache/adapter-common

Common classes for PSR-6 adapters

11124.4M38](/packages/cache-adapter-common)[amphp/redis

Efficient asynchronous communication with Redis servers, enabling scalable and responsive data storage and retrieval.

165634.7k44](/packages/amphp-redis)[ethanhann/redisearch-php

239113.6k1](/packages/ethanhann-redisearch-php)[shopware/core

Shopware platform is the core for all Shopware ecommerce products.

595.2M386](/packages/shopware-core)[neos/cache

Neos Cache Framework

102.0M31](/packages/neos-cache)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
