wildduck/lib/counters.js

89 lines
2.4 KiB
JavaScript
Raw Normal View History

'use strict';
const Scripty = require('node-redis-scripty');
2017-07-18 16:17:36 +08:00
const ttlCounterScript = `
local key = KEYS[1];
local increment = tonumber(ARGV[1]) or 0;
local limit = tonumber(ARGV[2]) or 0;
2017-07-18 16:17:36 +08:00
local current = tonumber(redis.call("GET", key)) or 0;
if current >= limit then
2017-07-18 16:17:36 +08:00
local ttl = tonumber(redis.call("TTL", key)) or 0;
return {0, current, ttl};
end;
2017-07-18 16:17:36 +08:00
local updated = tonumber(redis.call("INCRBY", key, increment));
if current == 0 then
2017-07-18 16:17:36 +08:00
redis.call("EXPIRE", key, 86400);
end;
2017-07-18 16:17:36 +08:00
local ttl = tonumber(redis.call("TTL", key)) or 0;
return {1, updated, ttl};
`;
2017-07-18 16:17:36 +08:00
const cachedCounterScript = `
local key = KEYS[1];
local increment = tonumber(ARGV[1]) or 0;
local ttl = tonumber(ARGV[2]) or 0;
if redis.call("EXISTS", key) == 1 then
redis.call("INCRBY", key, increment);
2017-07-20 21:42:08 +08:00
local sum = tonumber(redis.call("GET", key)) or 0;
2017-07-18 16:17:36 +08:00
-- extend the life of this counter by ttl seconds
redis.call("EXPIRE", key, ttl);
2017-07-20 21:42:08 +08:00
return sum;
2017-07-18 16:17:36 +08:00
else
return nil;
end
`;
module.exports = redis => {
let scripty = new Scripty(redis);
return {
ttlcounter(key, count, max, callback) {
2017-07-18 16:17:36 +08:00
scripty.loadScript('ttlcounter', ttlCounterScript, (err, script) => {
if (err) {
return callback(err);
}
script.run(1, key, count, max, (err, res) => {
if (err) {
return callback(err);
}
return callback(null, {
2017-06-03 14:51:58 +08:00
success: !!((res && res[0]) || 0),
value: (res && res[1]) || 0,
ttl: (res && res[2]) || 0
});
});
});
2017-07-18 16:17:36 +08:00
},
cachedcounter(key, count, ttl, callback) {
scripty.loadScript('cachedCounter', cachedCounterScript, (err, script) => {
if (err) {
return callback(err);
}
2017-07-20 21:42:08 +08:00
script.run(
1,
key,
count,
ttl,
(
err,
res => {
if (err) {
return callback(err);
}
callback(null, res);
}
)
);
2017-07-18 16:17:36 +08:00
});
}
};
};