diff --git a/README.md b/README.md index 69fa899..cd48eed 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,14 @@ prerender-mongodb-cache ======================= -Prerender plugin for MongoDB caching, to be used with the prerender node application from https://github.com/prerender/prerender. +Prerender plugin for MongoDB caching, to be used with the prerender node application from https://github.com/prerender/prerender. It relys on [cache-manager](https://github.com/BryanDonovan/node-cache-manager) and on the [mongo adapter](https://github.com/v4l3r10/node-cache-manager-mongodb) How it works ------------ This plugin will store all prerendered pages into a MongoDB instance. There is currently no expiration functionality, which means that once a page is stored, future requests for prerendering a page will always be served from from the database cache if it's available and the page caches are never updated. -To get a fresh cache, you will have to delete the cache in the MongoDB instance manually or from another process. +To set the cache lifetime use the environment variable when launching prerender: `CACHE_TTL` (in seconds) by default it has been set to one month. How to use ---------- @@ -19,7 +19,9 @@ In your local prerender project run: Then in the server.js that initializes the prerender: - server.use(require('prerender-mongodb-cache')); +```js +server.use(require('prerender-mongodb-cache')); +``` Configuration ------------- @@ -27,3 +29,9 @@ Configuration By default it will connect to your MongoDB instance running on localhost and use the *prerender* collection. You can overwrite this by setting the `MONGOLAB_URI` or `MONGOHQ_URL` environment variables to valid MongoDB connection strings. This is done to make it work automatically when deployed on Heroku with the MongoDB add-ons. + +Contributions +------------- + +Creator: [lammertw](https://github.com/lammertw) +Contributor: [YouriT](https://github.com/YouriT) diff --git a/lib/mongoCache.js b/lib/mongoCache.js index 7156d72..ebacd96 100644 --- a/lib/mongoCache.js +++ b/lib/mongoCache.js @@ -5,58 +5,85 @@ var mongoUri = process.env.MONGOLAB_URI || process.env.MONGOHQ_URL || 'mongodb://localhost/prerender'; -var database; +var ttl = process.env.CACHE_TTL || 2592000; -MongoClient.connect(mongoUri, function(err, db) { - database = db; -}); - -var cache_manager = require('cache-manager'); +var cacheManager = require('cache-manager'), + mongoStore = require('cache-manager-mongodb'), + mongoCache; module.exports = { init: function() { - this.cache = cache_manager.caching({ - store: mongo_cache + mongoCache = cacheManager.caching({ + store: mongoStore, + uri: mongoUri, + options: { + collection: "pages", + compression: false, + server: { + poolSize: 5, + auto_reconnect: true + } + }, + ttl: ttl }); }, beforePhantomRequest: function(req, res, next) { - if(req.method !== 'GET') { + + var currentTTL = req.headers['cache-ttl'] || ttl; + + var url = req.url.replace(/%(25)+/gi, '%').replace(/%3f\_escaped\_fragment.*/gi, ''); + var parts = req.url.split('/'), + lastPart = parts[parts.length - 1]; + try { + url = url.replace(lastPart, decodeURIComponent(lastPart).replace(/\?\_escaped\_fragment.*/g, '')); + } catch (e) {}; + + if (req.method !== 'GET') { return next(); } - this.cache.get(req.url, function (err, result) { - if (!err && result) { - res.send(200, result); - } else { - next(); - } - }); + + try { + mongoCache.get(url, function(err, result) { + if (err) { + throw err; + } + if (!err && result) { + res.send(200, result); + } else { + next(); + } + }); + } catch (e) { + console.log(e.stack || e.message); + next(); + } }, afterPhantomRequest: function(req, res, next) { - this.cache.set(req.url, req.prerender.documentHTML); - next(); - } -}; + var currentTTL = req.headers['cache-ttl'] || ttl; -var mongo_cache = { - get: function(key, callback) { - database.collection('pages', function(err, collection) { - collection.findOne({key: key}, function (err, item) { - var value = item ? item.value : null; - callback(err, value); - }); - }); - }, - set: function(key, value, callback) { - database.collection('pages', function(err, collection) { - var object = {key: key, value: value, created: new Date()}; - collection.update({key: key}, object, { - upsert: true - }, function (err) { + var url = req.url.replace(/%(25)+/gi, '%').replace(/%3f\_escaped\_fragment.*/gi, ''); + var parts = req.url.split('/'), + lastPart = parts[parts.length - 1]; + try { + url = url.replace(lastPart, decodeURIComponent(lastPart).replace(/\?\_escaped\_fragment.*/g, '')); + } catch (e) {}; + + try { + mongoCache.set(url, req.prerender.documentHTML, { + ttl: currentTTL + }, function(err) { + if (err) { + throw err; + } + next(); }); - }); + } catch (e) { + console.log(e.stack || e.message); + next(); + } } }; diff --git a/package.json b/package.json index f3c35bb..a632b65 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ }, "homepage": "https://github.com/lammertw/prerender-mongodb-cache", "dependencies": { - "mongodb": "~2.1.0", - "cache-manager": "0.2.0" + "cache-manager": "^1.3.0", + "cache-manager-mongodb": "^0.1.6" } }