PHPackages                             mimatus/locksmith - 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. mimatus/locksmith

ActiveLibrary

mimatus/locksmith
=================

v0.2.0(2mo ago)801[2 issues](https://github.com/MiMatus/Locksmith/issues)MITPHPPHP &gt;=8.3CI passing

Since Jan 25Pushed 2mo agoCompare

[ Source](https://github.com/MiMatus/Locksmith)[ Packagist](https://packagist.org/packages/mimatus/locksmith)[ RSS](/packages/mimatus-locksmith/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (2)Dependencies (4)Versions (8)Used By (0)

[![image](https://private-user-images.githubusercontent.com/52460843/531738343-1b7f034c-0cef-46b4-bf56-42529bffc827.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NzU0MjAyODksIm5iZiI6MTc3NTQxOTk4OSwicGF0aCI6Ii81MjQ2MDg0My81MzE3MzgzNDMtMWI3ZjAzNGMtMGNlZi00NmI0LWJmNTYtNDI1MjliZmZjODI3LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNjA0MDUlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjYwNDA1VDIwMTMwOVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTBkNGUzZDRjNmQwOWQ1OGRlNWMzMGYwNjY0ZmEyZjBiNmE0MjAxMmM5NTkxNThlZGE3NTc3M2QxNzNmMjhmMDkmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.yKz51B60O78iUOWvCLArjX8qMGOF5mKBBS6n1NeGeyo)](https://private-user-images.githubusercontent.com/52460843/531738343-1b7f034c-0cef-46b4-bf56-42529bffc827.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NzU0MjAyODksIm5iZiI6MTc3NTQxOTk4OSwicGF0aCI6Ii81MjQ2MDg0My81MzE3MzgzNDMtMWI3ZjAzNGMtMGNlZi00NmI0LWJmNTYtNDI1MjliZmZjODI3LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNjA0MDUlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjYwNDA1VDIwMTMwOVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTBkNGUzZDRjNmQwOWQ1OGRlNWMzMGYwNjY0ZmEyZjBiNmE0MjAxMmM5NTkxNThlZGE3NTc3M2QxNzNmMjhmMDkmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.yKz51B60O78iUOWvCLArjX8qMGOF5mKBBS6n1NeGeyo)Locksmith
=========

[](#locksmith)

PHP 8.3+ library which helps to manage execution in concurent situations (async code, parallel, distributed systems).

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

[](#installation)

```
composer require mimatus/locksmith
```

Features
--------

[](#features)

- Mutual exclusion / exclusive locks / mutex / serialized execution / semaphore with capacity 1 - lot of buzzwords describing ensurance resource/code is accessed/executed only once
- Semaphore / shared lock - limit access to resource N times at the same time
- Deadlock prevention via max lock wait time and cooperative suspension points
- Versioned locks - resource is locked only for higher/equal versions - prevents processing of outdated data/code
- Async/concurrent-friendly - cooperative suspension points to allow other lock acquisition attempts or allow lock TTL checks for long running processes
- TTL-based locks - locks are held only for specified time
- In-memory semaphore implementation for single-process scenarios
- Redis-based semaphore implementation for multi-process/distributed scenarios
- Extendable via `Semaphore` interface - implement your own semaphore (e.g., Redis-based, database-based, etc.)
- Deadlock prevention via max lock wait time and cooperative suspension points

Roadmap
-------

[](#roadmap)

- Basic in-memory &amp; Redis semaphore implementation
- Redlock algorithm for Redis semaphore
- Predis support for Redis semaphore
- AMPHP Redis client support for Redis semaphore
- First class support and tests for Redis 7 | Redis 8 | Valkey 9
- Feedback and API stabilization
- Redis Cluster support
- Documentation improvements
- MySQL/MariaDB/PostgreSQL semaphore implementation

Usage
-----

[](#usage)

Note

Project is still in early stages of development, so API is not stable yet and may change. Feedback is very welcome to help shape the API and make it more intuitive and easy to use.

### In-Memory semaphore

[](#in-memory-semaphore)

For single-process scenarios you can use in-memory semaphore implementation. It allows to limit concurrent access to resource within single process (e.g., number of concurrent HTTP requests, background jobs, or other tasks).

It's suitable mainly for concurrent PHP - AMPHP, Swoole, ReactPHP, etc.

It's not suitable for multi-process scenarios (e.g., multiple PHP-FPM workers, multiple servers) as each process/server will have its own instance of in-memory semaphore. For multi-process scenarios you should use Redis-based semaphore implementation.

```
$locksmith = new Locksmith(
    semaphore: new InMemorySemaphore(maxConcurrentLocks: 1) // Single lock at a time -> mutex
);

$resource = new Resource(
    namespace: 'test-resource', // Namespace/identifier for resource
    version: 1, // Optional resource version
);

$locked = $locksmith->locked(
    $resource,
    lockTTLNs: 1_000_000_000, // How long should be resource locked
    maxLockWaitNs: 500_000_000, // How long to wait for lock acquisition - error if exceeded
    minSuspensionDelayNs: 10_000 // Minimum delay between retries when lock acquisition fails
);

$locked(function (Closure $suspension): void {
    // Critical section - code executed under lock

    $suspension(); // Optional - cooperative suspension point to allow other lock acquisition attempts or allow lock TTL checks for long running processes
});

// Lock is released after callback execution
```

### Redis semaphore

[](#redis-semaphore)

For distributed scenarios you can use Redis-based semaphore implementation.

Supported Redis servers:

- Redis 7+
- Valkey 9+

Supported Redis clients:

- PhpRedis
- Predis
- AMPHP Redis client

```
$redis = new Redis();
$redis->connect('redis');
$phpRedisCleint = new PhpRedisClient($redis);

$semaphore = new RedisSemaphore(
    redisClient: $phpRedisCleint,
    maxConcurrentLocks: 3, // Max concurrent locks
);

$locksmith = new Locksmith(semaphore: $semaphore);

$resource = new Resource(
    namespace: 'test-resource', // Namespace/identifier for resource
    version: 1, // Optional resouce version
);

$locked = $locksmith->locked(
    $resource,
    lockTTLNs: 1_000_000_000, // How long should be resource locked
    maxLockWaitNs: 500_000_000, // How long to wait for lock acquisition - error if exceeded
    minSuspensionDelayNs: 10_000 // Minimum delay between retries when lock acquisition fails
);

$locked(function (Closure $suspension): void {
    // Critical section - code executed under lock

    $suspension(); // Optional - cooperative suspension point to allow other lock acquisition attempts or allow lock TTL checks for long running processes
});
// Lock is released after callback execution
```

### Distributed semaphore

[](#distributed-semaphore)

Distributed semaphore allows to use multiple semaphore instances (e.g., multiple Redis instances) to achieve higher availability and fault tolerance. It uses quorum-based approach - single lock is successful only if the defined quorum of semaphores is reached.

Implementation of distributed semaphore is based on [Redlock algorithm](https://redis.io/docs/latest/develop/clients/patterns/distributed-locks/#the-redlock-algorithm) with some adjustments to fit the `Semaphore` interface and allow cooperative suspension points.

Note

It's important to note that while distributed semaphore can be used Redis instances, it does not have first class support for Redis Cluster or Sentinel. First class support for Redis Cluster is on the roadmap, but in the meantime you can use distributed semaphore with multiple independent Redis instances as a workaround.

```
$semaphores = new SemaphoreCollection([
    new RedisSemaphore(
        redisClient: $redisClient1,
        maxConcurrentLocks: 3,
    ),
    new RedisSemaphore(
        redisClient: $redisClient2,
        maxConcurrentLocks: 3,
    ),
    new RedisSemaphore(
        redisClient: $redisClient3,
        maxConcurrentLocks: 3,
    ),
]);

$locksmith = new Locksmith(
    semaphore: new DistributedSemaphore(
        semaphores: $semaphores,
        quorum: 2,
    ),
);
$resource = new Resource(
    namespace: 'test-resource', // Namespace/identifier for resource
    version: 1, // Optional resource version
);
$locked = $locksmith->locked(
    $resource,
    lockTTLNs: 1_000_000_000, // How long should be resource locked
    maxLockWaitNs: 500_000_000, // How long to wait for lock acquisition - error if exceeded
    minSuspensionDelayNs: 10_000 // Minimum delay between retries when lock acquisition fails
);
$locked(function (Closure $suspension): void {
    // Critical section - code executed under lock

    $suspension(); // Optional - cooperative suspension point to allow other lock acquisition attempts or allow lock TTL checks for long running processes
});
// Lock is released after callback execution
```

Development
-----------

[](#development)

### Commits

[](#commits)

Project follows [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) for commit messages.

### Helpers

[](#helpers)

All necessary commands are available via `Makefile`.

To see all available commands:

```
make help
```

The most important ones:

```
composer-install: Install PHP dependencies via Composer.
help: Show help for each of the Makefile recipes.
mago-analyze: Run static analysis via mago.
mago-format: Run code formatting via mago.
mago-lint-fix: Run linting with auto-fix via mago.
mago-lint: Run linting via mago.
run-tests: Run tests via PHPUnit.
```

License
-------

[](#license)

MIT — see [License](License).

###  Health Score

36

—

LowBetter than 82% of packages

Maintenance79

Regular maintenance activity

Popularity7

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity44

Maturing project, gaining track record

 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 ~28 days

Total

2

Last Release

85d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/943f580788acea907fe6435ad5ca785487d02039ee3f29c92b4554cff4e210e0?d=identicon)[MiMatus](/maintainers/MiMatus)

---

Top Contributors

[![MiMatus](https://avatars.githubusercontent.com/u/52460843?v=4)](https://github.com/MiMatus "MiMatus (5 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/mimatus-locksmith/health.svg)

```
[![Health](https://phpackages.com/badges/mimatus-locksmith/health.svg)](https://phpackages.com/packages/mimatus-locksmith)
```

PHPackages © 2026

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