From 56852389560c97e4c5198c27f44cbbf622ad4b69 Mon Sep 17 00:00:00 2001 From: Thaddee Tyl Date: Mon, 7 Apr 2014 23:29:30 +0000 Subject: [PATCH] Using Redis to store analytics on Heroku. --- Makefile | 13 ++++++++++++- package.json | 1 + server.js | 55 +++++++++++++++++++++++++++++++++++++++++++--------- 3 files changed, 59 insertions(+), 10 deletions(-) diff --git a/Makefile b/Makefile index 99c401b..23964da 100644 --- a/Makefile +++ b/Makefile @@ -17,4 +17,15 @@ deploy: git push origin gh-pages:gh-pages) || git checkout master git checkout master -.PHONY: all favicon website deploy +setup: + curl http://download.redis.io/releases/redis-2.8.8.tar.gz >redis.tar.gz \ + && tar xf redis.tar.gz \ + && rm redis.tar.gz \ + && mv redis-2.8.8 redis \ + && cd redis \ + && make + +redis: + ./redis/src/redis-server + +.PHONY: all favicon website deploy setup redis diff --git a/package.json b/package.json index d31123b..338a2de 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "phantomjs": "~1.9.2-6", "es6-promise": "~0.1.1", "request": "~2.34.0", + "redis": "~0.10.1", "camp": "~13.11.9" }, "devDependencies": { diff --git a/server.js b/server.js index 7146f95..1207a50 100644 --- a/server.js +++ b/server.js @@ -11,24 +11,61 @@ var serverStartTime = new Date((new Date()).toGMTString()); // Analytics +var redis; +// Use Redis by default. +var useRedis = true; +if (process.env.REDISTOGO_URL) { + var redisToGo = require('url').parse(process.env.REDISTOGO_URL); + redis = require('redis').createClient(redisToGo.port, redisToGo.hostname); + redis.auth(redisToGo.auth.split(':')[1]); +} else { + redis = require('redis').createClient(); +} +redis.on('error', function() { + useRedis = false; +}); + var analytics = {}; var analyticsAutoSaveFileName = './analytics.json'; var analyticsAutoSavePeriod = 10000; setInterval(function analyticsAutoSave() { - fs.writeFile(analyticsAutoSaveFileName, JSON.stringify(analytics)); + if (useRedis) { + redis.set(analyticsAutoSaveFileName, JSON.stringify(analytics)); + } else { + fs.writeFileSync(analyticsAutoSaveFileName, JSON.stringify(analytics)); + } }, analyticsAutoSavePeriod); // Auto-load analytics. function analyticsAutoLoad() { - try { - analytics = JSON.parse(fs.readFileSync(analyticsAutoSaveFileName)); - } catch(e) { - // In case something happens on the 36th. - analytics.vendorMonthly = new Array(36); - analytics.rawMonthly = new Array(36); - resetMonthlyAnalytics(analytics.vendorMonthly); - resetMonthlyAnalytics(analytics.rawMonthly); + if (useRedis) { + redis.get(analyticsAutoSaveFileName, function(err, value) { + if (err == null && value != null) { + // if/try/return trick: + // if error, then the rest of the function is run. + try { + analytics = JSON.parse(value); + return; + } catch(e) {} + } + // In case something happens on the 36th. + analytics.vendorMonthly = new Array(36); + analytics.rawMonthly = new Array(36); + resetMonthlyAnalytics(analytics.vendorMonthly); + resetMonthlyAnalytics(analytics.rawMonthly); + }); + } else { + // Not using Redis. + try { + analytics = JSON.parse(fs.readFileSync(analyticsAutoSaveFileName)); + } catch(e) { + // In case something happens on the 36th. + analytics.vendorMonthly = new Array(36); + analytics.rawMonthly = new Array(36); + resetMonthlyAnalytics(analytics.vendorMonthly); + resetMonthlyAnalytics(analytics.rawMonthly); + } } }