Last week, we discussed Distributed Locking. Today, we’ll continue with it but doing it differently: with a full backflip. We'll see how and why to implement locks with queuing. Then we'll take it to the higher level, discussing how that relates to our regular apps and handling business workflows.
Yes, here’s a Node.js implementation of the Lock interface using JavaScript. It works with Promises and the async/await pattern, suitable for Node.js environments.
---
Lock Interface in JavaScript (Node.js)
class Lock {
constructor() {
this.locks = new Set();
}
async acquire({ lockId }) {
while (this.locks.has(lockId)) {
// Wait until the lock is available
await new Promise(resolve => setTimeout(resolve, 10));
await new Promise(resolve => setTimeout(resolve, 1000));
} finally {
await lock.release({ lockId: 'my-resource' });
}
}
async function safeCriticalSection() {
await lock.withAcquire(async () => {
console.log('Safely acquired lock');
await new Promise(resolve => setTimeout(resolve, 1000));
}, { lockId: 'my-resource' });
}
async function main() {
// Try to acquire and release a lock manually
await criticalSection();
// Use the withAcquire helper to ensure release
await safeCriticalSection();
}
main().catch(console.error);
---
✅ How It Works
1. acquire → Waits until the lock is available.
2. tryAcquire → Tries to acquire the lock without waiting; returns true or false.
3. release → Releases the lock; returns true if successful.
4. withAcquire → Acquires the lock, executes the function, and automatically releases the lock.
---
💡 Why This Works in Node.js
The Set object provides fast O(1) lookups and inserts for lock management.
The setTimeout + Promise combination allows cooperative waiting.
async/await ensures clean handling of asynchronous operations and guarantees lock release with finally.
---
🚀 Improvements & Extensions
You could extend this to support:
Lock timeouts (to avoid deadlocks).
Fair scheduling (to ensure locks are acquired in order of request).
Cluster-wide locking using Redis or other shared storage for distributed locks.
This implementation is thread-safe within a single Node.js instance and works well for in-memory locking. Let me know if you want to extend it to a distributed environment!
Yes, here’s a Node.js implementation of the Lock interface using JavaScript. It works with Promises and the async/await pattern, suitable for Node.js environments.
---
Lock Interface in JavaScript (Node.js)
class Lock {
constructor() {
this.locks = new Set();
}
async acquire({ lockId }) {
while (this.locks.has(lockId)) {
// Wait until the lock is available
await new Promise(resolve => setTimeout(resolve, 10));
}
this.locks.add(lockId);
}
async tryAcquire({ lockId }) {
if (this.locks.has(lockId)) {
return false;
}
this.locks.add(lockId);
return true;
}
async release({ lockId }) {
return this.locks.delete(lockId);
}
async withAcquire(handle, { lockId }) {
await this.acquire({ lockId });
try {
return await handle();
} finally {
await this.release({ lockId });
}
}
}
---
Example Usage
Here’s how you can use the lock implementation:
const lock = new Lock();
async function criticalSection() {
const acquired = await lock.tryAcquire({ lockId: 'my-resource' });
if (!acquired) {
console.log('Failed to acquire lock');
return;
}
try {
console.log('Doing work...');
await new Promise(resolve => setTimeout(resolve, 1000));
} finally {
await lock.release({ lockId: 'my-resource' });
}
}
async function safeCriticalSection() {
await lock.withAcquire(async () => {
console.log('Safely acquired lock');
await new Promise(resolve => setTimeout(resolve, 1000));
}, { lockId: 'my-resource' });
}
async function main() {
// Try to acquire and release a lock manually
await criticalSection();
// Use the withAcquire helper to ensure release
await safeCriticalSection();
}
main().catch(console.error);
---
✅ How It Works
1. acquire → Waits until the lock is available.
2. tryAcquire → Tries to acquire the lock without waiting; returns true or false.
3. release → Releases the lock; returns true if successful.
4. withAcquire → Acquires the lock, executes the function, and automatically releases the lock.
---
💡 Why This Works in Node.js
The Set object provides fast O(1) lookups and inserts for lock management.
The setTimeout + Promise combination allows cooperative waiting.
async/await ensures clean handling of asynchronous operations and guarantees lock release with finally.
---
🚀 Improvements & Extensions
You could extend this to support:
Lock timeouts (to avoid deadlocks).
Fair scheduling (to ensure locks are acquired in order of request).
Cluster-wide locking using Redis or other shared storage for distributed locks.
This implementation is thread-safe within a single Node.js instance and works well for in-memory locking. Let me know if you want to extend it to a distributed environment!
If you want to reach out to me you can this is how I implemented it using chat GPT