machinepack-redis
Advanced tools
Comparing version 0.2.0 to 1.0.0
@@ -10,13 +10,14 @@ module.exports = { | ||
extendedDescription: 'This may involve opening a new connection, or aquiring an already-open connection from an existing pool. The implementation is left up to the driver.', | ||
moreInfoUrl: 'https://github.com/NodeRedis/node_redis#rediscreateclient', | ||
inputs: { | ||
connectionString: { | ||
description: 'A string containing all metadata and credentials necessary for connecting to the database.', | ||
example: 'redis://127.0.0.1:6379', | ||
manager: { | ||
friendlyName: 'Manager', | ||
description: 'The connection manager instance to acquire the connection from.', | ||
extendedDescription: | ||
'Only managers built using the `createManager()` method of this driver are supported. '+ | ||
'Also, the database connection manager instance provided must not have been destroyed--'+ | ||
'i.e. once `destroyManager()` is called on a manager, no more connections can be acquired '+ | ||
'from it (also note that all existing connections become inactive-- see `destroyManager()` '+ | ||
'for more on that).', | ||
example: '===', | ||
required: true | ||
@@ -27,5 +28,4 @@ }, | ||
friendlyName: 'Meta (custom)', | ||
description: 'Additional Redis-specific options to use when connecting.', | ||
extendedDescription: 'If specified, should be a dictionary.', | ||
moreInfoUrl: 'https://github.com/NodeRedis/node_redis#options-is-an-object-with-the-following-possible-properties', | ||
description: 'Additional stuff to pass to the driver.', | ||
extendedDescription: 'This is reserved for custom driver-specific extensions. Please refer to the documentation for the driver you are using for more specific information.', | ||
example: '===' | ||
@@ -50,15 +50,4 @@ } | ||
malformed: { | ||
description: 'The provided connection string is malformed (the driver DID NOT ATTEMPT to acquire a connection).', | ||
extendedDescription: 'The format of connection strings varies across different databases and their drivers. This exit indicates that the provided string is not valid as per the custom rules of this driver.', | ||
outputVariableName: 'report', | ||
outputDescription: 'The `error` property is a JavaScript Error instance explaining that (and preferably "why") the provided connection string is invalid. The `meta` property is reserved for custom driver-specific extensions.', | ||
example: { | ||
error: '===', | ||
meta: '===' | ||
} | ||
}, | ||
failedToConnect: { | ||
description: 'Could not acquire a connection to the database using the specified connection string.', | ||
failed: { | ||
description: 'Could not acquire a connection to the database using the specified manager.', | ||
extendedDescription: 'This might mean any of the following:\n'+ | ||
@@ -84,31 +73,11 @@ ' + the credentials encoded in the connection string are incorrect\n'+ | ||
var util = require('util'); | ||
var Url = require('url'); | ||
var redis = require('redis'); | ||
// Validate connection string (call `malformed` if invalid). | ||
try { | ||
Url.parse(inputs.connectionString); | ||
} | ||
catch (e) { | ||
e.message = | ||
'Provided value (`'+inputs.connectionString+'`) is not a valid Redis connection string: '+ | ||
e.message; | ||
return exits.malformed({ | ||
error: e | ||
}); | ||
} | ||
// Build a local variable (`redisClientOptions`) to house a dictionary | ||
// of additional Redis client options that will be passed into createClient(). | ||
// (this is pulled from the `meta` input) | ||
// (this is pulled from the `meta` maanger) | ||
// | ||
// For a complete list of available options, see: | ||
// • https://github.com/NodeRedis/node_redis#options-is-an-object-with-the-following-possible-properties | ||
var redisClientOptions = {}; | ||
if ( !util.isUndefined(inputs.meta) ) { | ||
if ( !util.isObject(inputs.meta) ) { | ||
return exits.error('If provided, `meta` must be a dictionary.'); | ||
} | ||
redisClientOptions = inputs.meta; | ||
} | ||
var redisClientOptions = inputs.manager.meta || undefined; | ||
@@ -118,3 +87,3 @@ // Create Redis client | ||
try { | ||
client = redis.createClient(inputs.connectionString, redisClientOptions); | ||
client = redis.createClient(inputs.manager.connectionString, redisClientOptions); | ||
} | ||
@@ -129,5 +98,5 @@ catch (e) { | ||
if (e.name === 'TypeError') { | ||
return exits.malformed({ error: e }); | ||
return exits.failed({ error: new Error('Invalid Redis client options in manager. Details: '+e.stack) }); | ||
} | ||
return exits.error(e); | ||
return exits.failed({ error: e }); | ||
} | ||
@@ -151,3 +120,3 @@ | ||
return exits.failedToConnect({ | ||
return exits.failed({ | ||
error: redisConnectionError || new Error('Redis client fired "end" event before it finished connecting.') | ||
@@ -176,15 +145,34 @@ }); | ||
client.on('error', function onIntraConnectionError(err){ | ||
// If manager was not provisioned with an `onUnexpectedFailure`, | ||
// we'll just handle this error event silently (to prevent crashing). | ||
if (!util.isFunction(inputs.manager.onUnexpectedFailure)) { return; } | ||
if (err) { | ||
if (/ECONNREFUSED/g.test(err)) { | ||
console.warn('Warning: Error emitted from Redis client: Connection to Redis server was lost (ECONNREFUSED). Waiting for Redis client to come back online (if configured to do so, auto-reconnecting behavior is happening in the background). Currently there are %d underlying Redis connections.', client.connections); | ||
inputs.manager.onUnexpectedFailure(new Error( | ||
'Error emitted from Redis client: Connection to Redis server was lost (ECONNREFUSED). '+ | ||
'Waiting for Redis client to come back online (if configured to do so, auto-reconnecting behavior '+ | ||
'is happening in the background). Currently there are '+client.connections+' underlying Redis connections.\n'+ | ||
'Error details:'+err.stack | ||
)); | ||
} | ||
else { | ||
console.warn('Warning: Error emitted from Redis client. Error details:',err); | ||
inputs.manager.onUnexpectedFailure(new Error('Error emitted from Redis client.\nError details:'+err.stack)); | ||
} | ||
} | ||
else { | ||
console.warn('Warning: Error emitted from Redis client. (no other information available)'); | ||
inputs.manager.onUnexpectedFailure(new Error('Error emitted from Redis client.\n (no other information available)')); | ||
} | ||
}); | ||
// Now track this Redis client as one of the "redisClients" on our manager | ||
// (since we want to be able to call destroyManager to wipe them all) | ||
inputs.manager.redisClients.push(client); | ||
// Save a reference to our manager instance on the redis client. | ||
if (client._fromWLManager){ | ||
return exits.error('Consistency violation: Somehow, a `_fromWLManager` key already exists on this Redis client instance!'); | ||
} | ||
client._fromWLManager = inputs.manager; | ||
// Finally, send back the Redis client as our active "connection". | ||
@@ -191,0 +179,0 @@ return exits.success({ |
@@ -52,3 +52,2 @@ module.exports = { | ||
example: { | ||
error: '===', | ||
meta: '===' | ||
@@ -64,3 +63,3 @@ } | ||
// Validate provided connection. | ||
// Validate provided connection (which is actually a redis client) | ||
if ( !util.isObject(inputs.connection) || !util.isFunction(inputs.connection.end) || !util.isFunction(inputs.connection.removeAllListeners) ) { | ||
@@ -70,2 +69,5 @@ return exits.badConnection(); | ||
// Grab a reference to the manager instance we piggybacked on this redis client. | ||
var mgr = inputs.connection._fromWLManager; | ||
// Release connection. | ||
@@ -78,5 +80,4 @@ try { | ||
// | ||
// (but not starting off that way because it could cause crashing | ||
// of the process if our `redis` dep decides to emit any "error" | ||
// events.) | ||
// (but not doing that unless absolutely necessary because it could cause crashing | ||
// of the process if our `redis` dep decides to emit any surprise "error" events.) | ||
} | ||
@@ -87,3 +88,14 @@ catch (e) { | ||
// Remove this redis client from the manager. | ||
var foundAtIndex = mgr.redisClients.indexOf(inputs.connection); | ||
if (foundAtIndex === -1) { | ||
return exits.badConnection({ | ||
meta: new Error('Attempting to release connection that is no longer referenced by its manager.') | ||
}); | ||
} | ||
mgr.redisClients.splice(foundAtIndex, 1); | ||
// And that's it! | ||
return exits.success(); | ||
} | ||
@@ -90,0 +102,0 @@ |
{ | ||
"name": "machinepack-redis", | ||
"version": "0.2.0", | ||
"version": "1.0.0", | ||
"description": "Structured Node.js bindings for Redis.", | ||
@@ -16,2 +16,3 @@ "scripts": { | ||
"dependencies": { | ||
"async": "1.5.2", | ||
"machine": "~12.0.0", | ||
@@ -27,2 +28,4 @@ "redis": "2.4.2" | ||
"machines": [ | ||
"create-manager", | ||
"destroy-manager", | ||
"get-connection", | ||
@@ -29,0 +32,0 @@ "release-connection" |
@@ -68,28 +68,38 @@ | ||
// Now you can use the connection however you like! | ||
// | ||
// To use the connection: | ||
// `report.connection` | ||
// This just keeps the process going. | ||
// console.log('mmk.'); | ||
// setInterval(function (){ | ||
// console.log('still goin mmmmhhhmm'); | ||
// }, 1000); | ||
// To release the connection: | ||
setTimeout(function (){ | ||
Redis.releaseConnection({ | ||
connection: report.connection | ||
}).exec({ | ||
error: function (err){ | ||
console.error('UNEXPECTED ERROR:',err); | ||
}, | ||
success: function (report){ | ||
console.log('Connection released.'); | ||
} | ||
var redisClient = report.connection; | ||
// | ||
// See http://www.sitepoint.com/using-redis-node-js/ for more, but as a quick example: | ||
redisClient.set('stuff', 'things', function(err, reply) { | ||
// If "SET" failed... | ||
if (err) { | ||
// Handle failed "SET" | ||
// ... | ||
console.error('SET failed:',err); | ||
// Always release the connection when finished: | ||
Redis.releaseConnection({ connection: redisClient }).exec({ | ||
error: function (err){ console.error('UNEXPECTED ERROR:',err); }, | ||
success: function (report){ console.log('Connection released.'); } | ||
}); | ||
return; | ||
} | ||
// Otherwise "SET" was successful. | ||
// Do stuff | ||
console.log('mmk set that.'); | ||
// .... | ||
// Always release the connection when finished: | ||
Redis.releaseConnection({ connection: redisClient }).exec({ | ||
error: function (err){ console.error('UNEXPECTED ERROR:',err); }, | ||
success: function (report){ console.log('Connection released.'); } | ||
}); | ||
}, 7000); | ||
});//</client.set | ||
} | ||
}); | ||
});//</Redis.getConnection> | ||
``` | ||
@@ -96,0 +106,0 @@ |
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
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
26095
9
416
1
120
3
+ Addedasync@1.5.2
+ Addedasync@1.5.2(transitive)