Pranor Lock — Distributed Lock Manager
Pranor Lock is a high-performance distributed locking manager for the Pranor ecosystem, providing cross-service mutual exclusion with lease-based locks, fencing tokens, reentrant locking, deadlock cycle detection, and metrics observability.
Features
- Lease-based Locks: Automatic expiration of locks to prevent permanent resource hangs.
- Reentrant Locks: Reentrant support via
client_idtracking (recursive acquisition). - Fencing Tokens: Monotonically increasing tokens to prevent stale writes/updates in concurrency.
- Deadlock Cycle Detection: Active graph cycle detection aborts cyclic lock wait queues with error status.
- Observability Metrics: Prometheus-compatible metric exporter endpoint.
- Lease Persistence: Crash-safe persistent lease locking via local JSON file-backing.
Getting Started
Prerequisites
- Go 1.20+ installed
Running locally
# Start in-memory mode on default port 8089
go run main.go
# Start on custom port
go run main.go --port 8090
API Specification
All endpoints support standard auth and tenant isolation headers.
1. Acquire Lock
Acquires a lock for a key. Blocks up to wait_ms if held, and supports reentrancy if matching client_id is supplied.
- Endpoint:
POST /api/locks/acquire - Request Payload:
{ "key": "payment-order-123", "owner": "worker-node-1", "client_id": "session-abc", "duration_ms": 30000, "wait_ms": 5000 } - Response (200 OK):
{ "status": "success", "lock": { "key": "payment-order-123", "owner": "worker-node-1", "client_id": "session-abc", "reentrancy_count": 1, "fencing_token": 15, "expires_at": "2026-07-17T20:25:00Z" } }
2. Renew Lock Lease
Extends active lease TTL. Rejects request if the provided fencing token does not match the active lock lease.
- Endpoint:
POST /api/locks/renew - Request Payload:
{ "key": "payment-order-123", "owner": "worker-node-1", "fencing_token": 15, "duration_ms": 30000 }
3. Release Lock
Frees the lock immediately. If reentrancy count is greater than 1, decrements count instead.
- Endpoint:
POST /api/locks/release - Request Payload:
{ "key": "payment-order-123", "owner": "worker-node-1", "fencing_token": 15 }
4. Observability & Metrics
List Active Locks
Retrieves list of active leases along with queued waiters.
- Endpoint:
GET /api/locks/observability
Prometheus Metrics
Retrieves Prometheus gauges/counters.
- Endpoint:
GET /api/locks/metrics
License
This project is licensed under Apache 2.0 - see the LICENSE file for details.