reliable-get
Advanced tools
Comparing version 0.1.2 to 0.1.3
@@ -44,3 +44,3 @@ 'use strict'; | ||
if(!url.parse(options.url).protocol) { return handleError({message:'Invalid URL ' + options.url}); } | ||
if(!url.parse(options.url).protocol && options.url !== 'cache') { return handleError({message:'Invalid URL ' + options.url}); } | ||
@@ -89,3 +89,3 @@ options.headers.accept = options.headers.accept || 'text/html,application/xhtml+xml,application/xml,application/json'; | ||
if(options.url == 'cache') { | ||
next(null, {}); | ||
next(null, {content: 'No content in cache at key: ' + options.cacheKey, statusCode: 404}); | ||
return; | ||
@@ -92,0 +92,0 @@ } |
@@ -14,3 +14,3 @@ 'use strict'; | ||
var obtainCacheInstance = function(config) { | ||
if(!engines[config.engine]) { return cacheInstance.nocache; } | ||
if(!config || !engines[config.engine]) { config = config || {}; config.engine = 'nocache'; } | ||
var Engine = engines[config.engine]; | ||
@@ -17,0 +17,0 @@ cacheInstance[config.engine] = cacheInstance[config.engine] || new Engine(config); |
@@ -25,3 +25,3 @@ 'use strict'; | ||
var redisClient = redis.createClient(redisConfig.port || null, redisConfig.host || null, redisConfig.options); | ||
self._redisClient = redis.createClient(redisConfig.port || null, redisConfig.host || null, redisConfig.options); | ||
@@ -31,11 +31,11 @@ // Prevent error events bubbling up to v8 and taking the worker down if redis is unavailable | ||
// re-establish the connection | ||
redisClient.on('error', function(err) { | ||
self._redisClient.on('error', function(err) { | ||
console.log('Error connecting to %s:%s - %s', redisConfig.host, redisConfig.port, err.message); | ||
}); | ||
redisClient.on('ready', function() { | ||
self._redisClient.on('ready', function() { | ||
self.emit('ready'); | ||
}); | ||
redisClient.select(redisConfig.db || 0); | ||
self._redisClient.select(redisConfig.db || 0); | ||
@@ -46,5 +46,5 @@ this.engine = 'redis'; | ||
if (!redisClient.connected) { return next(); } | ||
if (!self._redisClient.connected) { return next(); } | ||
redisClient.hgetall(key, function(err, data) { | ||
self._redisClient.hgetall(key, function(err, data) { | ||
@@ -66,3 +66,3 @@ if(!data) { return next(err, null); } | ||
if (!redisClient.connected) { return next(); } | ||
if (!self._redisClient.connected) { return next(); } | ||
@@ -73,3 +73,3 @@ if (arguments.length === 3) { return this.set(key, value, _ttl, function() {}); } | ||
var expires = Date.now() + ttl*1; | ||
var multi = redisClient.multi(); | ||
var multi = self._redisClient.multi(); | ||
@@ -76,0 +76,0 @@ multi.hset(key, 'content', value.content); |
{ | ||
"name": "reliable-get", | ||
"version": "0.1.2", | ||
"version": "0.1.3", | ||
"description": "A circuit breaker and cached wrapper for GET requests (enables reliable external service interaction).", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -16,2 +16,20 @@ 'use strict'; | ||
it('should default to nocache if invalid cache specified', function(done) { | ||
cacheFactory.clearCacheInstances(); | ||
cache = cacheFactory.getCache({engine:'invalid'}); | ||
cache.set('bar:123', 'content', 1000, function(err) { | ||
expect(err).to.be(null); | ||
assertCachedValue(cache, 'bar:123', null, done); | ||
}); | ||
}); | ||
it('should default to nocache if no cache specified', function(done) { | ||
cacheFactory.clearCacheInstances(); | ||
cache = cacheFactory.getCache(); | ||
cache.set('bar:123', 'content', 1000, function(err) { | ||
expect(err).to.be(null); | ||
assertCachedValue(cache, 'bar:123', null, done); | ||
}); | ||
}); | ||
function assertCachedValue(cache, key, expected, next) { | ||
@@ -18,0 +36,0 @@ cache.get(key, function(err, actual) { |
@@ -26,2 +26,13 @@ 'use strict'; | ||
it('should set and get values from cache without set callback', function(done) { | ||
withCache({engine:'redis'}, function(err, cache) { | ||
cache.set('bar:223', {content:'content', headers:{'header':'1'}}, 1000); | ||
setTimeout(function() { | ||
assertCachedValue(cache, 'bar:223', 'content', function() { | ||
assertHeaderValue(cache, 'bar:223', 'header', '1', done); | ||
}); | ||
}, 200); // Long enough | ||
}); | ||
}); | ||
it('should return null when value not present', function(done) { | ||
@@ -46,3 +57,2 @@ withCache({engine:'redis'}, function(err, cache) { | ||
it('should set and get values from cache', function(done) { | ||
@@ -95,2 +105,19 @@ withCache({engine:'redis'}, function(err, cache) { | ||
it('should fail silently if redis connection terminates', function(done) { | ||
var cache = cacheFactory.getCache({engine:'redis', url: 'redis://localhost'}); | ||
cache.set('bar:125', {content:'content', headers:{'header':'1'}}, 1000, function(err) { | ||
expect(err).to.be(undefined); | ||
cache._redisClient.quit(); | ||
cache._redisClient.emit('error', {message:'Test Redis error message'}); | ||
setTimeout(function() { | ||
cache.get('bar:125', function(err, data) { | ||
expect(err).to.be(undefined); | ||
expect(data).to.be(undefined); | ||
cacheFactory.clearCacheInstances(); // Set back into good state | ||
done(); | ||
}); | ||
}, 200); | ||
}); | ||
}); | ||
function withCache(config, next) { | ||
@@ -97,0 +124,0 @@ var cache = cacheFactory.getCache(config); |
@@ -10,2 +10,4 @@ 'use strict'; | ||
this.slow(10000); | ||
before(function(done) { | ||
@@ -26,2 +28,11 @@ var stubServer = require('./stub/server'); | ||
it('NO CACHE: should fail with an invalid url', function(done) { | ||
var config = {cache:{engine:'nocache'}}; | ||
var rg = new ReliableGet(config); | ||
rg.get({url:'Can I haz url?'}, function(err, response) { | ||
expect(err.statusCode).to.be(500); | ||
done(); | ||
}); | ||
}); | ||
it('NO CACHE: should fail if it calls a service that is broken', function(done) { | ||
@@ -66,6 +77,6 @@ var config = {cache:{engine:'nocache'}}; | ||
var rg = new ReliableGet(config); | ||
rg.get({url:'http://localhost:5001/faulty?faulty=false', cacheKey: 'memory-faulty-2', cacheTTL: 200}, function(err, response) { | ||
rg.get({url:'http://localhost:5001/faulty?faulty=false', cacheKey: 'memory-faulty-2', cacheTTL: 10000}, function(err, response) { | ||
expect(err).to.be(null); | ||
expect(response.statusCode).to.be(200); | ||
rg.get({url:'http://localhost:5001/faulty?faulty=true', cacheKey: 'memory-faulty-2', cacheTTL: 200}, function(err, response) { | ||
rg.get({url:'http://localhost:5001/faulty?faulty=true', cacheKey: 'memory-faulty-2', cacheTTL: 10000}, function(err, response) { | ||
expect(err).to.be(null); | ||
@@ -94,2 +105,56 @@ expect(response.statusCode).to.be(200); | ||
it('MEMORY CACHE: should return whatever is in cache at the cache key if the url is "cache"', function(done) { | ||
var config = {cache:{engine:'memorycache'}}; | ||
var rg = new ReliableGet(config); | ||
rg.get({url:'cache', cacheKey:'memory-faulty-2', cacheTTL: 10000}, function(err, response) { | ||
expect(response.statusCode).to.be(200); | ||
expect(response.content).to.be('Faulty service managed to serve good content!'); | ||
done(); | ||
}); | ||
}); | ||
it('MEMORY CACHE: should return 404 if nothing is in cache at the cache key if the url is "cache"', function(done) { | ||
var config = {cache:{engine:'memorycache'}}; | ||
var rg = new ReliableGet(config); | ||
rg.get({url:'cache', cacheKey:'invalid-key', cacheTTL: 10000}, function(err, response) { | ||
expect(response.statusCode).to.be(404); | ||
expect(response.content).to.be('No content in cache at key: invalid-key'); | ||
done(); | ||
}); | ||
}); | ||
it('MEMORY CACHE: should honor no-cache cache-control headers ', function(done) { | ||
var config = {cache:{engine:'memorycache'}}; | ||
var rg = new ReliableGet(config); | ||
rg.get({url:'http://localhost:5001/nocache', cacheKey: 'memory-nocache-1', cacheTTL: 10000}, function(err, response) { | ||
expect(err).to.be(null); | ||
expect(response.statusCode).to.be(200); | ||
var content = response.content; | ||
setTimeout(function() { | ||
rg.get({url:'http://localhost:5001/nocache', cacheKey: 'memory-nocache-1', cacheTTL: 10000}, function(err, response) { | ||
expect(response.statusCode).to.be(200); | ||
expect(response.content).to.not.be(content); | ||
done(); | ||
}); | ||
}, 500); | ||
}); | ||
}); | ||
it('MEMORY CACHE: should honor max age cache-control headers', function(done) { | ||
var config = {cache:{engine:'memorycache'}}; | ||
var rg = new ReliableGet(config); | ||
rg.get({url:'http://localhost:5001/maxage', cacheKey: 'memory-maxage-1', cacheTTL: 50}, function(err, response) { | ||
expect(err).to.be(null); | ||
expect(response.statusCode).to.be(200); | ||
var content = response.content; | ||
setTimeout(function() { | ||
rg.get({url:'http://localhost:5001/maxage', cacheKey: 'memory-maxage-1', cacheTTL: 50}, function(err, response) { | ||
expect(response.statusCode).to.be(200); | ||
expect(response.content).to.be(content); | ||
done(); | ||
}); | ||
}, 500); | ||
}); | ||
}); | ||
it('REDIS CACHE: should serve from cache after initial request', function(done) { | ||
@@ -96,0 +161,0 @@ var config = {cache:{engine:'redis'}}; |
@@ -33,5 +33,17 @@ 'use strict'; | ||
}); | ||
router.get('/broken', function(req, res) { | ||
req.socket.end(); | ||
}); | ||
router.get('/nocache', function(req, res) { | ||
res.writeHead(200, {'cache-control': 'private, max-age=0, no-cache'}); | ||
res.end('' + Date.now()); | ||
}); | ||
router.get('/maxage', function(req, res) { | ||
res.writeHead(200, {'cache-control': 'private, max-age=5000'}); | ||
res.end('' + Date.now()); | ||
}); | ||
router.get('/faulty', faultyFn); | ||
@@ -38,0 +50,0 @@ router.get('/cb-faulty', faultyFn); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
40852
869