CartoDB-SQL-API/batch/leader/locker.js

70 lines
2.0 KiB
JavaScript
Raw Normal View History

'use strict';
var RedisDistlockLocker = require('./provider/redis-distlock');
var debug = require('../util/debug')('leader-locker');
2016-10-12 19:11:20 +08:00
var LOCK = {
TTL: 5000
};
function Locker(locker, ttl) {
this.locker = locker;
2016-10-12 19:11:20 +08:00
this.ttl = (Number.isFinite(ttl) && ttl > 0) ? ttl : LOCK.TTL;
this.renewInterval = this.ttl / 5;
2016-10-12 18:30:13 +08:00
this.intervalIds = {};
}
module.exports = Locker;
2016-10-14 19:10:27 +08:00
Locker.prototype.lock = function(resource, callback) {
2016-10-12 18:30:13 +08:00
var self = this;
2016-10-14 19:10:27 +08:00
debug('Locker.lock(%s, %d)', resource, this.ttl);
this.locker.lock(resource, this.ttl, function (err, lock) {
if (!err) {
2016-10-14 19:10:27 +08:00
self.startRenewal(resource);
}
2016-10-12 18:30:13 +08:00
return callback(err, lock);
});
};
2016-10-14 19:10:27 +08:00
Locker.prototype.unlock = function(resource, callback) {
2016-10-12 18:30:13 +08:00
var self = this;
2016-10-14 19:10:27 +08:00
debug('Locker.unlock(%s)', resource);
this.locker.unlock(resource, function(err) {
self.stopRenewal(resource);
2016-10-12 18:30:13 +08:00
return callback(err);
});
};
2016-10-14 19:10:27 +08:00
Locker.prototype.startRenewal = function(resource) {
2016-10-12 18:30:13 +08:00
var self = this;
2016-10-14 19:10:27 +08:00
if (!this.intervalIds.hasOwnProperty(resource)) {
this.intervalIds[resource] = setInterval(function() {
debug('Trying to extend lock resource=%s', resource);
self.locker.lock(resource, self.ttl, function(err, _lock) {
2016-10-12 18:30:13 +08:00
if (err) {
2016-10-14 19:10:27 +08:00
return self.stopRenewal(resource);
2016-10-12 18:30:13 +08:00
}
if (_lock) {
2016-10-14 19:10:27 +08:00
debug('Extended lock resource=%s', resource);
2016-10-12 18:30:13 +08:00
}
});
2016-10-12 19:11:20 +08:00
}, this.renewInterval);
2016-10-12 18:30:13 +08:00
}
};
2016-10-14 19:10:27 +08:00
Locker.prototype.stopRenewal = function(resource) {
if (this.intervalIds.hasOwnProperty(resource)) {
clearInterval(this.intervalIds[resource]);
delete this.intervalIds[resource];
2016-10-12 18:30:13 +08:00
}
};
module.exports.create = function createLocker(type, config) {
if (type !== 'redis-distlock') {
throw new Error('Invalid type Locker type. Valid types are: "redis-distlock"');
}
2016-10-17 21:02:34 +08:00
var locker = new RedisDistlockLocker(config.pool);
2016-10-12 19:11:20 +08:00
return new Locker(locker, config.ttl);
};