Lockserver
Lockserver is a distributed lock server for coordinating access to shared resources across multiple workers or processes. It provides an HTTP API and official client libraries for Rust (with ergonomic macros), Node.js, and Python for easy distributed locking in any environment.
Features
- Simple API for acquiring and releasing locks
- Official client libraries for Rust, Node.js, and Python
- Ergonomic Rust macros (
lock_scope!) - Blocking and non-blocking lock acquisition
- Lock expiration: Optionally set an expiration (in seconds) when acquiring a lock; expired locks are auto-released
Security: Shared Secret Authorization
All client requests must include a shared secret for authorization. The server and client must agree on the same secret, set via the LOCKSERVER_SECRET environment variable or .env file. The client sends this secret in the X-LOCKSERVER-SECRET HTTP header.
Example .env:
LOCKSERVER_SECRET=your-strong-secret
Server:
LOCKSERVER_SECRET=your-strong-secret
cargo run --release
Client:
LOCKSERVER_SECRET=your-strong-secret
Or pass the secret directly to the client constructor.
You can configure the bind IP and HTTP port using CLI arguments, environment variables, or a .env file (using dotenvy):
CLI arguments (override env/.env):
# or short form:
Environment variables or .env file:
LOCKSERVER_BIND_IP=127.0.0.1
LOCKSERVER_PORT=9000
Then just run:
HTTP API (default port 8080)
- Acquire a lock:
POST /acquirewith JSON{ "resource": "myres", "owner": "worker1" [, "expire": 10] }- Optional
expire(seconds): lock will be auto-released after this many seconds
- Optional
- Release a lock:
POST /releasewith JSON{ "resource": "myres", "owner": "worker1" }
Example using curl (with secret and expiration):
Client SDKs
- Rust: See below and the integration tests in
tests/lock_scope_macro.rs.acquire_with_mode_and_expire(resource, mode, expire)allows setting expiration in seconds
- Node.js: js-client/ (npm)
acquire(resource, blocking = true, expire)supports expiration (in seconds)
- Python: python-client/ (PyPI)
acquire(resource, blocking=True, expire=None)supports expiration (in seconds)
Rust Example
Add to your Cargo.toml:
[]
= "0.1"
use ;
// Loads from env/.env if None (including secret)
let client = new_with_env;
lock_scope!;
// Override address, owner, or secret:
let client = new_with_env;
// Non-blocking mode:
if let Ok = client.acquire_with_mode
// With expiration:
if let Ok = client.acquire_with_mode_and_expire
See the respective README.md in each client directory for Node.js and Python usage and installation instructions.
License
Licensed under the MIT License.