Last active
August 18, 2020 13:36
-
-
Save yashLadha/022444fac5edc7d712b0590b0423035a to your computer and use it in GitHub Desktop.
Native Mutex Implementation in NodeJS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
const EventEmitter = require('events'); | |
class NativeLock extends EventEmitter { | |
lockState = new Map(); | |
constructor() { | |
super(); | |
this.on('lock', this.handleLockAquire); | |
this.on('release', this.releaseLock); | |
} | |
releaseLock(key, res) { | |
console.log(`Releasing lock for ${key}`); | |
this.lockState.delete(key); | |
res(); | |
} | |
async handleLockAquire(key, res) { | |
console.log(`Acquiring lock for ${key}`); | |
this.lockState.set(key, 'acquired'); | |
res(); | |
} | |
release(key) { | |
return new Promise((res) => { | |
this.emit('release', key, res); | |
}); | |
} | |
static delay(ms) { | |
return new Promise((res) => { | |
setTimeout(res, ms); | |
}); | |
} | |
acquire(key) { | |
return new Promise((res) => { | |
// Leveraging TCO (Tail call optimization) | |
// for recusrive calls and not overflowing the stack | |
// frames | |
const timer = async () => { | |
if (this.lockState.has(key)) { | |
console.log(`Lock already acquired for ${key}`); | |
await NativeLock.delay(50); | |
return timer(); | |
} | |
this.emit('lock', key, res); | |
}; | |
timer(); | |
}); | |
} | |
} | |
// Lock object to handle the locking in asynchronous code | |
const lock = new NativeLock(); | |
const KEY = 'sameKey'; | |
const OTHER_KEY = 'anotherKey'; | |
const main = async() => { | |
await Promise.all(Array.from(Array(5)).map(async (_, idx) => { | |
const localKey = idx % 2 === 0 ? KEY : OTHER_KEY; | |
await lock.acquire(localKey); | |
// Having some action for 5 seconds | |
await NativeLock.delay(5000); | |
await lock.release(localKey); | |
})); | |
} | |
main(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment