In redis sentinel client program - first program, when i keep the redis sentinel object to be created and it works fine to set the KEY . But when you observe the second program , client.on('connect', runSample(client)); I am passing the client object ( redis sentinel client ), its on connect parameter runSample. For this I am getting the following error ..
Error Details
https://github.com/DocuSignDev/node-redis-sentinel-client/blob/master/index.js
RedisSentinelClient.prototype.send_command undefined
/node_modules/redis-sentinel-client/index.js:293
return client.send_command.apply(client, arguments);
^
TypeError: Cannot read property 'send_command' of undefined
at RedisSentinelClient.send_command (/node_modules/redis-sentinel-client/index.js:293:16)
at RedisSentinelClient.(anonymous function).RedisSentinelClient.(anonymous function) (/node_modules/redis-sentinel-client/index.js:307:23)
at runSample (/msg/lb4.expire.onefile.2m.notworking.js:25:13)
at init (/msg/lb4.expire.onefile.2m.notworking.js:16:26)
at Object.<anonymous> (/msg/lb4.expire.onefile.2m.notworking.js:75:1)
at Module._compile (module.js:460:26)
at Object.Module._extensions..js (module.js:478:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Function.Module.runMain (module.js:501:10)
RajRajen:pubsub.local rajrajen$
First working program..
'use strict';
var client = getRedisSentinelObject();
client.on('error', function(err) {
console.log('Error ' + err);
});
client.on('connect', runSample);
function runSample() {
var allStrings = '{abc:123}';
client.get(allStrings, function(err, reply) {
if (reply) {
console.log('Key is ' + reply.toString());
client.ttl(allStrings, writeTTL);
} else {
console.log('string key expired or not set before!');
// Set a value
client.set(allStrings, allStrings);
// Expire in 3 seconds
client.expire(allStrings, 3);
}
client.quit();
});
}
function getRedisSentinelObject() {
var redisSentinelHost = process.env.REDIS_SENTINEL_SERVICE_HOST;
var redisSentinelPort = process.env.REDIS_SENTINEL_SERVICE_PORT;
var options = {
'master_debug': false
};
var redisSentinelMasterDebug = process.env.REDIS_SENTINEL_MASTER_DEBUG;
if (typeof redisSentinelMasterDebug !== "undefined") {
if (redisSentinelMasterDebug === "true") {
options.master_debug = true;
}
}
console.log('redisSentinelHost ', redisSentinelHost, 'redisSentinelPort ', redisSentinelPort);
var RedisSentinel = require('redis-sentinel-client');
var sentinelClient = RedisSentinel.createClient(redisSentinelPort, redisSentinelHost, options);
console.log('sentinelClient ', sentinelClient);
return sentinelClient;
}
function writeTTL(err, data) {
console.log('I live for this long yet: ', data);
}
Second program, that is not working
'use strict';
function init() {
var client = getRedisSentinelObject();
client.on('error', function(err) {
console.log('Error ' + err);
});
client.on('connect', runSample(client));
}
function runSample(client1) {
var allStrings = '{abc:123}';
client1.get(allStrings, function(err, reply) {
if (reply) {
console.log('Key is ' , reply.toString());
client1.ttl(allStrings, writeTTL);
} else {
console.log('string key expired or not set before!');
// Set a value
client1.set(allStrings, allStrings);
// Expire in 3 seconds
client1.expire(allStrings, 2);
}
// client1.quit();
});
}
function getRedisSentinelObject() {
var redisSentinelHost = process.env.REDIS_SENTINEL_SERVICE_HOST;
var redisSentinelPort = process.env.REDIS_SENTINEL_SERVICE_PORT;
var options = {
'master_debug': false
};
var redisSentinelMasterDebug = process.env.REDIS_SENTINEL_MASTER_DEBUG;
if (typeof redisSentinelMasterDebug !== "undefined") {
if (redisSentinelMasterDebug === "true") {
options.master_debug = true;
}
}
console.log('redisSentinelHost ', redisSentinelHost, 'redisSentinelPort ', redisSentinelPort);
var RedisSentinel = require('redis-sentinel-client');
var sentinelClient = RedisSentinel.createClient(redisSentinelPort, redisSentinelHost, options);
console.log('sentinelClient ', sentinelClient);
return sentinelClient;
}
function writeTTL(err, data) {
console.log('I live for this long yet: ', data);
}
init();
Thanks
In example 1 you have the line:
client.on('connect', runSample);
This line attaches a function to be run when the client connects. All is good. Please note that the function is not run until the client connects.
In example 2, the same line looks like this:
client.on('connect', runSample(client));
In this line, the runSample
method is executed immediately. The result of this function call (in this case undefined
) is then passed into client.on
. So if we do a little bit of the evaluation by hand here, the javascript boils down to:
client.on('connect', undefined);
This fails because you're telling redis, "When you connect, nothing".
The easiest way to fix this is to use a closure (a function that absorbs it's scope). This is most likely what you meant to do.
client.on('connect', function () {
runSample(client)
});
If you wanted to make things a bit more complicated, you could make a function like this:
function buildRunner (client) {
return function runTests () {
var allStrings = '{abc:123}';
client.get(allStrings, function(err, reply) {
if (reply) {
console.log('Key is ' + reply.toString());
client.ttl(allStrings, writeTTL);
} else {
console.log('string key expired or not set before!');
// Set a value
client.set(allStrings, allStrings);
// Expire in 3 seconds
client.expire(allStrings, 3);
}
client.quit();
});
}
}
And use it like:
client.on('connect', buildRunner(client));
Please note that buildRunner
will be executed immediately, just like before. The difference is that buildRunner
returns a function that gets passed into client.on
. If we do some evaluation by hand again, we get:
client.on('connect', function runTests () { ... })
// ^ runTests is holding on to an internal copy of `client` because
// `client` existed back when we built runTests
// up in `buildRunner`