FIX: better locks (rel #3)

This commit is contained in:
Overtorment
2019-01-07 16:40:32 +00:00
parent 98ba940342
commit b7073abb0e
3 changed files with 70 additions and 17 deletions

47
class/Lock.js Normal file
View File

@@ -0,0 +1,47 @@
const crypto = require('crypto');
export class Lock {
/**
*
* @param {Redis} redis
* @param {String} lock_key
*/
constructor(redis, lock_key) {
this._redis = redis;
this._lock_key = lock_key;
}
/**
* Tries to obtain lock in single-threaded Redis.
* Returns TRUE if success.
*
* @returns {Promise<boolean>}
*/
async obtainLock() {
if (await this._redis.get(this._lock_key)) {
// someone already has the lock
return false;
}
// trying to set the lock:
let buffer = crypto.randomBytes(10);
const randomValue = buffer.toString('hex');
await this._redis.set(this._lock_key, randomValue);
// checking if it was set:
let value = await this._redis.get(this._lock_key);
if (value !== randomValue) {
// someone else managed to obtain this lock
return false;
}
// success - got lock
await this._redis.expire(this._lock_key, 2 * 60);
// lock expires in 2 mins just for any case
return true;
}
async releaseLock() {
await this._redis.del(this._lock_key);
}
}

View File

@@ -1 +1,2 @@
export * from './User';
export * from './Lock';