New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

apostrophe-caches-redis

Package Overview
Dependencies
Maintainers
1
Versions
8
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

apostrophe-caches-redis - npm Package Compare versions

Comparing version 2.0.0 to 2.1.0

140

index.js

@@ -6,2 +6,3 @@ // TODO:

var redis = require("redis");
var Promise = require('bluebird');

@@ -30,62 +31,105 @@ module.exports = {

return {
// Fetch an item from the cache. If the item is in the
// cache, the callback receives (null, item). If the
// item is not in the cache the callback receives (null).
// If an error occurs the callback receives (err).
// If there is no callback a promise is returned.
get: function(key, callback) {
key = self.prefix + name + ':' + key;
return self.client.get(key, function(err, json) {
if (err) {
return callback(err);
}
if (json === null) {
return callback(null);
}
var data;
try {
data = JSON.parse(json);
} catch (e) {
return callback(e);
}
return callback(null, data);
});
if (callback) {
return body(callback);
} else {
return Promise.promisify(body)();
}
function body(callback) {
key = self.prefix + name + ':' + key;
return self.client.get(key, function(err, json) {
if (err) {
return callback(err);
}
if (json === null) {
return callback(null);
}
var data;
try {
data = JSON.parse(json);
} catch (e) {
return callback(e);
}
return callback(null, data);
});
}
},
// Store an item in the cache. `value` may be any JSON-friendly
// value, including an object. `lifetime` is in seconds.
//
// The callback receives (err).
//
// You may also call with just three arguments:
// key, value, callback. In that case there is no hard limit
// on the lifetime, however NEVER use a cache for PERMANENT
// storage of data. It might be cleared at any time.
//
// If there is no callback a promise is returned.
set: function(key, value, lifetime, callback) {
if (!callback) {
callback = lifetime;
if (arguments.length === 2) {
lifetime = 0;
}
key = self.prefix + name + ':' + key;
if (lifetime) {
return self.client.setex(key, lifetime, JSON.stringify(value), callback);
return Promise.promisify(body)();
} else if (arguments.length === 3) {
if (typeof(lifetime) === 'function') {
callback = lifetime;
lifetime = 0;
return body(callback);
} else {
return Promise.promisify(body)();
}
} else {
return self.client.set(key, JSON.stringify(value), callback);
return body(callback);
}
function body(callback) {
key = self.prefix + name + ':' + key;
if (lifetime) {
return self.client.setex(key, lifetime, JSON.stringify(value), callback);
} else {
return self.client.set(key, JSON.stringify(value), callback);
}
}
},
// Empty the cache. If there is no callback a promise is returned.
clear: function(callback) {
// This is not as simple as it sounds:
//
// https://stackoverflow.com/questions/4006324/how-to-atomically-delete-keys-matching-a-pattern-using-redis
//
// I'm avoiding Lua because of comments in that article that it might not play nice
// with Redis clustering.
//
// Use of `keys` is not deprecated as long as it's for a special-purpose, occasional operation,
// and clearing an entire cache qualifies.
return self.client.keys(self.prefix + name + ':*', function(err, keys) {
if (err) {
return callback(err);
}
removeNextBatch();
function removeNextBatch() {
if (!keys.length) {
return callback(null);
if (callback) {
return body(callback);
} else {
return Promise.promisify(body)();
}
function body(callback) {
// This is not as simple as it sounds:
//
// https://stackoverflow.com/questions/4006324/how-to-atomically-delete-keys-matching-a-pattern-using-redis
//
// I'm avoiding Lua because of comments in that article that it might not play nice
// with Redis clustering.
//
// Use of `keys` is not deprecated as long as it's for a special-purpose, occasional operation,
// and clearing an entire cache qualifies.
return self.client.keys(self.prefix + name + ':*', function(err, keys) {
if (err) {
return callback(err);
}
return self.client.del(keys.slice(0, 1000), function(err) {
if (err) {
return callback(err);
removeNextBatch();
function removeNextBatch() {
if (!keys.length) {
return callback(null);
}
keys = keys.slice(1000);
return removeNextBatch();
});
}
});
return self.client.del(keys.slice(0, 1000), function(err) {
if (err) {
return callback(err);
}
keys = keys.slice(1000);
return removeNextBatch();
});
}
});
}
}

@@ -92,0 +136,0 @@ };

{
"name": "apostrophe-caches-redis",
"version": "2.0.0",
"version": "2.1.0",
"description": "Redis-based cache for the Apostrophe CMS",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"test": "mocha test/test.js"
},

@@ -25,2 +25,3 @@ "repository": {

"dependencies": {
"bluebird": "^3.5.1",
"redis": "^2.7.1"

@@ -31,6 +32,3 @@ },

"apostrophe": "^2.0.0"
},
"scripts": {
"test": "mocha test/test.js"
}
}

@@ -32,1 +32,5 @@ This module enhances `apostrophe-caches`, the standard caching mechanism of Apostrophe, to use Redis rather than MongoDB.

You can do that too, and it greatly reduces the load on MongoDB. You don't need this module for that. See [storing sessions in Redis](http://apostrophecms.org/docs/tutorials/howtos/storing-sessions-in-redis.html).
## Changelog
2.1.0: promise support. The `get`, `set` and `clear` methods of caches now return promises if no callback is given, matching the behavior of Apostrophe's core cache.
var assert = require('assert');
var _ = require('lodash');
var async = require('async');
var Promise = require('bluebird');

@@ -10,2 +11,3 @@ describe('Apostrophe cache implementation in redis', function() {

it('initializes apostrophe', function(done) {
this.timeout(5000);
apos = require('apostrophe')({

@@ -33,2 +35,14 @@ testModule: true,

});
it('can clear cache 1', function(done) {
return cache1.clear(function(err) {
assert(!err);
done();
});
});
it('can clear cache 2', function(done) {
return cache2.clear(function(err) {
assert(!err);
done();
});
});
it('can store 2000 keys in cache 1', function(done) {

@@ -114,3 +128,73 @@ var vals = _.range(0, 2000);

});
it('can clear cache 1 with promises', function() {
return cache1.clear();
});
it('can clear cache 2 with promises', function() {
return cache2.clear();
});
it('can store 2000 keys in cache 1 with promises', function() {
var vals = _.range(0, 2000);
return Promise.each(vals, function(val) {
return cache1.set(val, val);
});
});
it('can store 2000 keys in cache 2 with promises', function() {
var vals = _.range(2000, 4000);
return Promise.each(vals, function(val) {
return cache2.set(val, val);
});
});
it('can retrieve key from cache 1 with promises', function() {
return cache1.get(1000)
.then(function(val) {
assert(val === 1000);
});
});
it('can retrieve key from cache 2 with promises', function() {
return cache2.get(3000)
.then(function(val) {
assert(val === 3000);
});
});
it('cannot retrieve cache 2 key from key 1 (namespacing) with promises', function() {
return cache1.get(3000)
.then(function(val) {
assert(!val);
});
});
it('can clear a cache with promises', function() {
return cache1.clear();
});
it('cannot fetch a key from a cleared cache with promises', function() {
return cache1.get(1000)
.then(function(val) {
assert(!val);
});
});
it('can fetch a key from an uncleared cache with promises', function() {
return cache2.get(3000)
.then(function(val) {
assert(val === 3000);
});
});
it('can store a key with a 1-second timeout with promises', function() {
return cache1.set('timeout', 'timeout', 1);
});
it('can fetch that key within the 1-second timeout with promises', function() {
return cache1.get('timeout', function(value) {
assert(value === 'timeout');
done();
});
});
it('cannot fetch that key after 2 seconds with promises', function() {
this.timeout(5000);
return Promise.delay(2000)
.then(function() {
return cache1.get('timeout')
})
.then(function(val) {
assert(!val);
});
});
});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc