Skip to content

Repository files navigation

lock logo

@prsm/lock

Distributed locking primitives for Redis. Mutex for exclusive locks, semaphore for N concurrent leases. All operations are atomic via Lua scripts, and locks auto-expire on crash via TTL.

Installation

npm install @prsm/lock

Mutex

Exclusive lock. One holder at a time.

import{mutex}from"@prsm/lock"constlock=mutex({redis: {host: "127.0.0.1",port: 6379},})const{ acquired, id }=awaitlock.acquire("my-job",{ttl: "30s"})if(!acquired)returntry{awaitdoWork()}finally{awaitlock.release("my-job",id)}

mutex(options)

  • redis - { url?, host?, port?, password? } passed to node-redis
  • prefix - Redis key prefix (default "lock:mutex:")

Methods

MethodReturnsDescription
acquire(key, opts?){ acquired, id }Attempt to acquire. opts.ttl (default "10s"), opts.id (custom holder ID)
release(key, id)booleanRelease only if you still own it
peek(key){ held, holder, ttl }Check lock state without acquiring
close()voidDisconnect Redis

Semaphore

Up to N concurrent holders.

import{semaphore}from"@prsm/lock"constsem=semaphore({max: 20,ttl: "60s",redis: {host: "127.0.0.1",port: 6379},})const{ acquired, id }=awaitsem.acquire("worker-slots")if(!acquired)returnconstheartbeat=setInterval(()=>sem.renew("worker-slots",id),15000)try{awaitprocessTask()}finally{clearInterval(heartbeat)awaitsem.release("worker-slots",id)}

semaphore(options)

  • max - Maximum concurrent holders (required)
  • ttl - Lease lifetime (default "60s"). Expired leases are pruned automatically
  • redis - Same as mutex
  • prefix - Redis key prefix (default "lock:sem:")

Methods

MethodReturnsDescription
acquire(key, opts?){ acquired, id }Acquire a lease slot. opts.id for custom lease ID
release(key, id)trueRelease a lease
renew(key, id)booleanExtend lease lifetime. false if expired
count(key)numberActive lease count (after pruning)
peek(key){ active, max, available, holders }Full semaphore state
close()voidDisconnect Redis

How It Works

Mutex uses SET key value NX PX ttl for atomic acquire and a Lua script for ownership-checked release (only the holder can release).

Semaphore uses a Redis sorted set where each member is a lease ID and the score is a timestamp. Expired entries are pruned via ZREMRANGEBYSCORE before each acquire. Renewal updates the timestamp to extend the lease window.

Both are crash-tolerant via TTLs. If a holder dies without releasing, the lock/lease expires automatically.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages