# @apiratorjs/locking-redis

[![NPM version](https://img.shields.io/npm/v/@apiratorjs/locking-redis.svg)](https://www.npmjs.com/package/@apiratorjs/locking-redis)
[![License: MIT](https://img.shields.io/npm/l/@apiratorjs/locking-redis.svg)](https://github.com/apiratorjs/locking-redis/blob/main/LICENSE)

An extension to the core [@apiratorjs/locking](https://github.com/apiratorjs/locking) library, providing Redis-based implementations of distributed mutexes and
semaphores for true cross-process concurrency control in Node.js.

> **Note:** Requires Node.js version **>=16.4.0**

> A running Redis instance (version 5+ recommended).

---

## Why Use Redis for Distributed Locking?

- **Multi-instance deployments**: If you have multiple Node.js processes or servers behind a load balancer, an in-memory
  lock is insufficient. Redis provides a single, centralized coordination point.
- **Fault tolerance**: Configurable timeouts (TTLs) prevent indefinite locks if a process crashes.
- **Scalability**: Redis can handle many simultaneous locking requests at scale.

---

## Features

- **Redis-Powered Distributed Mutex and Semaphore**. Enables multi-process or multi-instance synchronization across a
  shared Redis server.
- **Compatible API**: Same DistributedMutex and DistributedSemaphore interface
  as [@apiratorjs/locking](https://github.com/apiratorjs/locking), so you can swap in Redis without changing the rest of
  your code.
- **Time-limited locks (TTL)**. Prevents deadlocks if processes crash without releasing.
- **Cancellation, Timeouts, and FIFO**. Cancel blocked acquisitions, specify timeouts, and queue waiters in a
  first-in-first-out manner.

---

## Installation

Install with npm:

```bash
npm install @apiratorjs/locking @apiratorjs/locking-redis
```

Or with yarn:

```bash
yarn add @apiratorjs/locking @apiratorjs/locking-redis
```

---

## Usage

```typescript
import { DistributedMutex, DistributedSemaphore } from "@apiratorjs/locking";
import { createRedisLockFactory } from "@apiratorjs/locking-redis";

async function setupRedisBackedLocks() {
  const lockFactory = await createRedisLockFactory({ url: "redis://localhost:6379" });

  // Override the default in-memory factory:
  DistributedMutex.factory = lockFactory.createDistributedMutex;
  DistributedSemaphore.factory = lockFactory.createDistributedSemaphore;
}

// Then anywhere else in your code:
const mutex = new DistributedMutex({ name: "global-mutex" });
// This will now automatically use Redis under the hood
```

---

## Contributing

Contributions, issues, and feature requests are welcome!
Please open an issue or submit a pull request on [GitHub](https://github.com/apiratorjs/locking-redis).
