Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
Redis client now working !
  • Loading branch information
tonyskn committed Nov 15, 2013
0 parents commit d117fbd
Show file tree
Hide file tree
Showing 6 changed files with 165 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.idea
node_modules
12 changes: 12 additions & 0 deletions examples/client.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
var TimeSeries = require('../'),
redis = require('redis'),
client = redis.createClient(),
ts = new TimeSeries(client);

client.on("error", function(err) { consoe.log("Error: ", err); });

ts.getHits("visits", "5minutes", 4, function(err, data) {
console.log(err, data);
});

client.quit();
15 changes: 15 additions & 0 deletions examples/hitter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
var redis = require('redis'),
TimeSeries = require('../'),
client = redis.createClient(),
ts = new TimeSeries(client),
i = 0;

client.on("error", function(err) { console.log("Error: ", err); });

setInterval(function() {
ts.recordHit("messages")
.recordHit("visits")
.exec(function() {
console.log("Recorded hit", new Date(), ++i);
});
}, 90 * 1000);
1 change: 1 addition & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('./src/timeseries.js');
20 changes: 20 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "redis-timeseries",
"version": "0.1.0",
"description": "Manage timeseries data storage in Redis with ease",
"main": "index.js",
"scripts": {
"test": "npm test"
},
"keywords": [
"Redis",
"Timeseries",
"Async"
],
"author": "Tony Sokhon",
"license": "MIT",
"dependencies": {
"redis": "~0.9.0",
"hiredis": "~0.1.15"
}
}
115 changes: 115 additions & 0 deletions src/timeseries.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@

var TimeSeries = module.exports = function(redis) {
this.redis = redis;
this.granularities = Object.keys(granularitiesConfig);
this.pendingMulti = redis.multi();
};

/**
* Record a hit for the specified stats entry
* This method is chainable:
* --> var ts = new TimeSeries(redis)
* .recordHit("messages")
* .recordHit("purchases")
* ...
* .exec([callback]);
*/
TimeSeries.prototype.recordHit = function(key) {
var self = this;

this.granularities.forEach(function(gran) {
var properties = granularitiesConfig[gran],
tsround = getRoundedTime(properties.size * properties.factor),
tmpKey = [key, gran, tsround].join(':'),
ts = getRoundedTime(properties.factor);

self.pendingMulti.hincrby(tmpKey, ts, 1);
self.pendingMulti.expireat(tmpKey, tsround + properties.ttl);
});

return this;
};

/**
* Execute the current pending redis multi
*/
TimeSeries.prototype.exec = function(callback) {
var self = this;

if (this.pendingMulti) {
this.pendingMulti.exec(function(err, result) {
self.pendingMulti = self.redis.multi();
callback(err, result);
});
}
};

/**
* getHits(redis, "messages", "10minutes", 3, cb)
* --> "messages" hits during the last 3 '10minutes' chunks
*/
TimeSeries.prototype.getHits = function(key, gran, count, callback) {
var properties = granularitiesConfig[gran],
currentTime = getCurrentTime();

if (typeof properties === "undefined") {
return callback(new Error("Unsupported granularity: "+gran));
}

var from = getRoundedTime(properties.factor, currentTime - count*properties.factor),
to = getRoundedTime(properties.factor, currentTime);

for(var ts=from, multi=this.redis.multi(); ts<=to; ts+=properties.factor) {
var tsround = getRoundedTime(properties.size * properties.factor, ts),
tmpKey = [key, gran, tsround].join(':');

multi.hget(tmpKey, ts);
}

multi.exec(function(err, results) {
if (err) {
return callback(err);
}

for(var ts=from, i=0, data=[]; ts<=to; ts+=properties.factor, i+=1) {
if (results[i]) {
data.push([ts, parseInt(results[i], 10)]);
}
}

return callback(null, data.slice(Math.max(data.length - count, 0)));
});
};

var granularitiesConfig = {
'5minutes': { // Available for 24 hours
size: 288,
ttl: 172800,
factor: 300
},
'10minutes': { // Available for 24 hours
size: 144,
ttl: 172800,
factor: 600
},
'hour': { // Available for 7 days
size: 168,
ttl: 1209600,
factor: 3600
},
'day': { // Available for 24 months
size: 365,
ttl: 63113880,
factor: 86400
}
};

var getCurrentTime = function() {
return Math.floor(Date.now() / 1000);
};

var getRoundedTime = function(precision, time) {
time = time || getCurrentTime();
return Math.floor(time / precision) * precision;
};

0 comments on commit d117fbd

Please sign in to comment.