persistence
Advanced tools
Comparing version 0.2.0 to 0.3.0
@@ -44,4 +44,6 @@ var Connection = require('./connection.js'); | ||
var connection = connections[name]; | ||
if (!connection || connection.name) | ||
if (!connection || !connection.name) { | ||
done(new Error('No connection found')); | ||
return; | ||
} | ||
@@ -48,0 +50,0 @@ connection.teardown(function() { |
var redisLib = require('redis'), | ||
Tracker = require('callback_tracker'), | ||
sentinelLib = require('redis-sentinel-client'), | ||
sentinelLib = require('redis-sentinel'), | ||
logging = require('minilog')('connection'); | ||
function redisConnect(config) { | ||
var client = redisLib.createClient(config.port, config.host); | ||
if (config.redis_auth) { | ||
client.auth(config.redis_auth); | ||
var propagateError = function(callback, error) { | ||
if(callback) { | ||
callback(error); | ||
} else { | ||
if(error instanceof Error) { | ||
throw error; | ||
} else { | ||
throw new Error(error); | ||
} | ||
} | ||
}; | ||
logging.info('Created a new Redis client.'); | ||
return client; | ||
} | ||
var connectionMethods = { | ||
redis: function (config, callback) { | ||
var client = redisLib.createClient(config.port, config.host); | ||
if (config.redis_auth) { | ||
client.auth(config.redis_auth); | ||
} | ||
function sentinelConnect(config) { | ||
var client, | ||
redisAuth = config.redis_auth, | ||
sentinelMaster = config.id, | ||
sentinels = config.sentinels, | ||
index, sentinelHost, sentinelPort; | ||
logging.info('Created a new Redis client.'); | ||
client.once('ready', function() { | ||
callback(null, client); | ||
}); | ||
}, | ||
if(!sentinels || !sentinels.length) { | ||
throw new Error('Provide a valid sentinel cluster configuration '); | ||
} | ||
sentinel: function (config, callback) { | ||
var sentinel, options = { role: 'sentinel' }, | ||
redisAuth = config.redis_auth, | ||
sentinelMaster = config.id, | ||
sentinels = config.sentinels; | ||
//Pick a random sentinel for now. | ||
//Only one is supported by redis-sentinel-client, | ||
//if it's down, let's hope the next round catches the right one. | ||
index = Math.floor(Math.random() * sentinels.length); | ||
sentinelHost = sentinels[index].host; | ||
sentinelPort = sentinels[index].port; | ||
if(!sentinels || !sentinels.length || !sentinelMaster) { | ||
propagateError(callback, new Error('Provide a valid sentinel cluster configuration ')); | ||
return; | ||
} | ||
if(!sentinelPort || !sentinelHost) { | ||
throw new Error('Provide a valid sentinel cluster configuration '); | ||
} | ||
if(redisAuth) { | ||
options.auth_pass = redisAuth; | ||
} | ||
sentinel = sentinelLib.createClient(sentinels, sentinelMaster, options); | ||
sentinel.send_command('SENTINEL', ['get-master-addr-by-name', sentinelMaster], function(error, master) { | ||
sentinel.quit(); | ||
client = sentinelLib.createClient(sentinelPort, sentinelHost, { | ||
auth_pass: redisAuth, | ||
masterName: sentinelMaster | ||
}); | ||
if(error) { | ||
callback(error); | ||
} | ||
logging.info('Created a new Sentinel client.'); | ||
return client; | ||
} | ||
if(!master || master.length != 2) { | ||
propagateError(callback, new Error("Unknown master "+sentinelMaster)); | ||
return; | ||
} | ||
var newConfig = { host: master[0], | ||
port: master[1], | ||
redis_auth: config.redis_auth }; | ||
connectionMethods.redis(newConfig, callback); | ||
}); | ||
} | ||
}; | ||
function Connection(name, config) { | ||
@@ -57,5 +76,5 @@ this.name = name; | ||
Connection.prototype.selectMethod = function() { | ||
var method = redisConnect; | ||
var method = 'redis'; | ||
if(this.config.id || this.config.sentinels) { | ||
method = sentinelConnect; | ||
method = 'sentinel'; | ||
} | ||
@@ -103,13 +122,21 @@ return method; | ||
var method = this.selectMethod(); | ||
var method = connectionMethods[this.selectMethod()]; | ||
//create a client (read/write) | ||
this.client = method(this.config); | ||
logging.info('Created a new client.'); | ||
this.client.once('ready', tracker('client ready :'+ this.name)); | ||
method(this.config, tracker('client ready :' + this.name, function(error, client) { | ||
if(error) { | ||
throw (error instanceof Error)? error : new Error(error); | ||
} | ||
logging.info('Created a new client.'); | ||
self.client = client; | ||
})); | ||
//create a pubsub client | ||
this.subscriber = method(this.config); | ||
logging.info('Created a new subscriber.'); | ||
this.subscriber.once('ready', tracker('subscriber ready :'+ this.name)); | ||
method(this.config, tracker('subscriber ready :'+ this.name, function(error, subscriber) { | ||
if(error) { | ||
throw (error instanceof Error)? error : new Error(error); | ||
} | ||
logging.info('Created a new subscriber.'); | ||
self.subscriber = subscriber; | ||
})); | ||
} | ||
@@ -116,0 +143,0 @@ }; |
{ | ||
"name": "persistence", | ||
"version": "0.2.0", | ||
"version": "0.3.0", | ||
"description": "An abstraction library for redis and sentinel connection management", | ||
@@ -24,6 +24,6 @@ "main": "persistence.js", | ||
"callback_tracker": "*", | ||
"redis": "0.10.1", | ||
"redis-sentinel-client": "0.1.5", | ||
"redis": "*", | ||
"redis-sentinel": "*", | ||
"minilog": "*" | ||
} | ||
} |
@@ -172,3 +172,9 @@ var logging = require('minilog')('persistence'), | ||
connected = false; | ||
connection.teardown(callback); | ||
if(connection && (connection.client || connection.subscriber)) { | ||
connection.teardown(callback); | ||
} else { | ||
if(callback) { | ||
callback(); | ||
} | ||
} | ||
}; | ||
@@ -175,0 +181,0 @@ |
@@ -1,9 +0,12 @@ | ||
var assert = require('assert'), | ||
Persistence = require('../persistence.js'), | ||
var assert = require('assert'), | ||
SentinelHelper = require('simple_sentinel'), | ||
Persistence = require('../persistence.js'), | ||
client; | ||
exports['given a resource'] = { | ||
describe('given a connected persistence', function() { | ||
before: function(done) { | ||
Persistence.setConfig({ redis_host: 'localhost', redis_port: 6379 }); | ||
before(function(done) { | ||
process.env.noverbose=true; | ||
SentinelHelper.start({ redis: { ports: [ 16379 ] } }); | ||
Persistence.setConfig({ redis_host: 'localhost', redis_port: 16379 }); | ||
Persistence.connect(function() { | ||
@@ -13,79 +16,85 @@ client = Persistence.redis(); | ||
}); | ||
}, | ||
}); | ||
after: function(done) { | ||
after(function(done) { | ||
Persistence.delWildCard('*', function() { | ||
Persistence.disconnect(done); | ||
Persistence.disconnect(function() { | ||
SentinelHelper.stop({ redis: { ports: [ 16379 ] } }); | ||
done(); | ||
}); | ||
}); | ||
}, | ||
}); | ||
'non JSON redis string should be filtered out (ie. do not return corrupted data)': function(done) { | ||
describe('after connection', function() { | ||
it('should be able to get client and subscriber', function() { | ||
assert.ok(Persistence.redis()); | ||
assert.ok(Persistence.pubsub()); | ||
}); | ||
}); | ||
describe('while handling errors', function() { | ||
it('should filter out non JSON redis strings (ie. do not return corrupted data)', function(done) { | ||
var key = 'persistence.test'; | ||
var key = 'persistence.test'; | ||
client.del(key, function() { | ||
client.hset(key, 'bar1', 'this string should be filtered out', function() { | ||
client.hset(key, 'bar2', '"this string should be returned"', function() { | ||
Persistence.readHashAll(key, function(result) { | ||
assert.deepEqual({ bar2: 'this string should be returned' }, result); | ||
done(); | ||
}); | ||
client.del(key); | ||
client.hset(key, 'bar1', 'this string should be filtered out'); | ||
client.hset(key, 'bar2', '"this string should be returned"', function() { | ||
Persistence.readHashAll(key, function(result) { | ||
assert.deepEqual({ bar2: 'this string should be returned' }, result); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}, | ||
describe('while persisting messages', function() { | ||
it('should serialize objects', function(done) { | ||
// (nherment) TODO: the result should actually be deserialized because it is being serialized in persistOrdered() | ||
// The problem is that radar_client currently deserializes the response. | ||
// We need to make the client not deserialize the response so that we can deserialize it here. | ||
'persisting messages serializes it when the message is an object': function(done) { | ||
// (nherment) TODO: the result should actually be deserialized because it is being serialized in persistOrdered() | ||
// The problem is that radar_client currently deserializes the response. | ||
// We need to make the client not deserialize the response so that we can deserialize it here. | ||
var key = 'persistence.messages.object.test'; | ||
var objectValue = { | ||
foo: 'bar' | ||
}; | ||
Persistence.persistOrdered(key, objectValue, function(err) { | ||
if(err) { | ||
return done(err); | ||
} | ||
Persistence.readOrderedWithScores(key, undefined, function(replies) { | ||
var key = 'persistence.messages.object.test'; | ||
var objectValue = { | ||
foo: 'bar' | ||
}; | ||
Persistence.persistOrdered(key, objectValue, function(err) { | ||
if(err) { | ||
return done(err); | ||
} | ||
Persistence.readOrderedWithScores(key, undefined, function(replies) { | ||
assert(replies instanceof Array); | ||
assert.equal(2, replies.length); | ||
assert.equal('string', typeof replies[0]); | ||
assert.equal(JSON.stringify(objectValue), replies[0]); | ||
done(); | ||
assert(replies instanceof Array); | ||
assert.equal(2, replies.length); | ||
assert.equal('string', typeof replies[0]); | ||
assert.equal(JSON.stringify(objectValue), replies[0]); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}, | ||
'persisting messages serializes it when the message is a string': function(done) { | ||
// (nherment) TODO: the result should actually be deserialized because it is being serialized in persistOrdered() | ||
// The problem is that radar_client currently deserializes the response. | ||
// We need to make the client not deserialize the response so that we can deserialize it here. | ||
it('should serialize strings', function(done) { | ||
// (nherment) TODO: the result should actually be deserialized because it is being serialized in persistOrdered() | ||
// The problem is that radar_client currently deserializes the response. | ||
// We need to make the client not deserialize the response so that we can deserialize it here. | ||
var key = 'persistence.messages.string.test'; | ||
var stringValue = 'Hello World'; | ||
var key = 'persistence.messages.string.test'; | ||
var stringValue = 'Hello World'; | ||
Persistence.persistOrdered(key, stringValue, function(err) { | ||
if(err) { | ||
return done(err); | ||
} | ||
Persistence.readOrderedWithScores(key, undefined, function(replies) { | ||
Persistence.persistOrdered(key, stringValue, function(err) { | ||
if(err) { | ||
return done(err); | ||
} | ||
Persistence.readOrderedWithScores(key, undefined, function(replies) { | ||
assert(replies instanceof Array); | ||
assert.equal(2, replies.length); | ||
assert.equal('string', typeof replies[0]); | ||
assert.equal(JSON.stringify(stringValue), replies[0]); | ||
done(); | ||
assert(replies instanceof Array); | ||
assert.equal(2, replies.length); | ||
assert.equal('string', typeof replies[0]); | ||
assert.equal(JSON.stringify(stringValue), replies[0]); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
} | ||
}); | ||
}; | ||
}); |
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
Wildcard dependency
QualityPackage has a dependency with a floating version range. This can cause issues if the dependency publishes a new major version.
Found 2 instances in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
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
28156
20
786
5
9
2
+ Addedredis-sentinel@*
+ Added@redis/bloom@1.2.0(transitive)
+ Added@redis/client@1.6.0(transitive)
+ Added@redis/graph@1.1.1(transitive)
+ Added@redis/json@1.0.7(transitive)
+ Added@redis/search@1.2.0(transitive)
+ Added@redis/time-series@1.1.0(transitive)
+ Addedcluster-key-slot@1.1.2(transitive)
+ Addedgeneric-pool@3.9.0(transitive)
+ Addedredis@0.12.14.7.0(transitive)
+ Addedredis-sentinel@0.3.3(transitive)
+ Addedwhen@3.7.8(transitive)
+ Addedyallist@4.0.0(transitive)
- Removedredis-sentinel-client@0.1.5
- Removedredis@0.10.1(transitive)
- Removedredis-sentinel-client@0.1.5(transitive)
Updatedredis@*