17

I just wanted to know, at the beginning of my NodeJS process, if Redis is started or not (so users session will be stored or not).

Here is what I have for the moment :

var session = require('express-session');
var RedisStore = require('connect-redis')(session);
var redis = require("redis");
var client = redis.createClient(global.redis.host, global.redis.port);

// Check if redis is running
var redisIsReady = false;
client.on('error', function(err) {
    redisIsReady = false;
    console.log('redis is not running');
    console.log(err);
});
client.on('ready', function() {
    redisIsReady = true;
    console.log('redis is running');
});

// Here I use express-session, but I want to set a store only if redis is ready
    sessOptions = {
        [...]
    }
    // Store setting
    if (redisIsReady) {
        sessOptions.store = new RedisStore({
            host: global.redis.host,
            port: global.redis.port
        });
    } else {
        console.log("redis is not running - sessions won't be written to disk");
    }
// app.use(session(sessOptions))

Here is what it's output in both cases (when Redis is running or not) :

redis is not running - sessions won't be written to disk
redis is not running
Error: Redis connection to 6379:localhost failed - connect ENOENT

So I have 2 questions :

  1. How can I do to check if redis is running before setting my SessionStore (is there anyway to check synchronously if redis is running) ?

  2. Why does it giving me an error even when redis is running ?

THANKS!


Note : I'm using default host/port (localhost, 6379) and the RedisStore works as expected.

Note 2 : I'm using Windows... but don't be affraid, it should have the same behavior!

Update : Question #2 answered by vmx => Thanks!

Update 2 : Question #1 answered by Nathan => Thanks!

Oliboy50
  • 2,661
  • 3
  • 27
  • 36
  • 1
    Did you really start the server (type `redis-server &`) ? – Denys Séguret Jun 15 '14 at 17:11
  • Yes, my RedisStore behaves as expected, Redis save user sessions successfully. I can retrieve my session using the redis_client terminal. I just can't connect to redis using createClient() – Oliboy50 Jun 15 '14 at 17:19
  • node_redis default behaviour is to queue commands from the moment you call `redis.createClient` until the connection is made, so it's well possible you can just instantiate a RedisStore and carry on with your business without having to check whether redis is ready. Give it a try. – Mahn Sep 03 '14 at 15:54

7 Answers7

15

How I have done this in the past is in between setting up the redis connection via

var client = redis.createClient(global.redis.port, global.redis.host);

and actually starting my application, whether that be express or a custom app, I just do a very simple query, such as:

client.get(this.testKey, function(err,res) {
  if(err) 
    throw err;

  if(res === expectedValue)
    return startApp();
});

Essentially just put the code to start your app inside of the callback to a redis query, and you will then know if redis is running based on the result.

Nathan
  • 409
  • 4
  • 15
  • 1
    Actually, I wanted to start my app even if redis wasn't running =/ – Oliboy50 Jun 15 '14 at 17:35
  • Well then instead of throwing an error like I did you could set a value of a boolean and then check if it's true before you try to store anything in redis. If client.get() fails to get a value from redis, it still will execute the callback function! – Nathan Jun 15 '14 at 18:04
  • Indeed. My project looks a bit more ugly now. But at least it works as expected. Thank you. – Oliboy50 Jun 15 '14 at 18:24
  • This works because node_redis queues the command until the connection is made, thus in effect the callback runs when redis is ready. But for most intents and purposes you don't need to rely on this, you can just start using redis rightaway and trust that things will be queued while the connection is being made. – Mahn Sep 03 '14 at 15:57
  • I get this error: `node_redis: Deprecated: The GET command contains a "undefined" argument. This is converted to a "undefined" string now and will return an error from v.3.0 on. Please handle this in your code to make sure everything works as you intended it to.` – Pini Cheyni Feb 21 '17 at 13:32
  • This doesn't seem like the best way IMHO. – Tyguy7 Oct 12 '19 at 00:16
8

2 issues, first the call to create Redis client is in wrong order, the createClient() takes port first, then the host, there's another optional options argument.

var client = redis.createClient(global.redis.port, global.redis.host);

Secondly, you will still not be able to achieve what you are trying to;

  1. The ready event is triggered asynchronously, it may not have received the ready response by the time you check for the redisIsReady flag.
  2. The flag redisIsReady will be set to true, but by now your session initialization code would have probably already executed.

You will have to wait before you get an error or ready event from redis before you initialize your session object.

Hope this helps.

vmx
  • 7,989
  • 4
  • 22
  • 20
  • Yep my bad for the arguments order... So now it works. But am I obliged to wait for redis answer before initialize my sessions... What if I must "app.use(session)" before "app.use(something-else)" ? – Oliboy50 Jun 15 '14 at 17:29
  • Use what Nathan has suggested, do a dummy query to check redis connectivity and initialize session accordingly. You can all app configuration and initialization code inside the query result callback. – vmx Jun 15 '14 at 17:33
  • Actually, I wanted to start my app even if redis wasn't running =/ – Oliboy50 Jun 15 '14 at 17:36
  • You will be able to run, no? Redis query will probably give you an error if it's not reachable/connected, you should initialize session to use memory store. If you get a result, use Redis store. – vmx Jun 15 '14 at 17:40
  • 1
    Thank you vmx, it works. I gave you +1 and I've accepted Nathan's answer (without +1), sounds fair. – Oliboy50 Jun 15 '14 at 18:26
  • This statement appears to be incorrect: "Secondly, you will still not be able to achieve what you are trying to". Reason: using the accepted answer I could achieve what the question asks for. – arnold Jun 30 '16 at 18:35
  • `You will have to *wait* before you get an error or ready event from redis before you initialize your session object` -- Exactly what the accepted answer tries to do. – vmx Jul 04 '16 at 07:22
6

Example:

 if (client.connected) {
    client.set(key, JSON.stringify(value));
  } else {
    console.log('redis not connected!');
  }
suraj gholap
  • 347
  • 4
  • 3
4

2023 Update:

To check if redis is running, simply use:

await client.connect();
  if(client.isOpen){ 
    //your code
  }

For using it more than once, it would be better to:

//check if redis is already running
if(!client.isOpen){
  await client.connect();
}
//your code
Mr.Pacific
  • 61
  • 4
0

You can also check using node redis api:

if (client.connected){
  ...
} else {
  ...
}
younes khanbaba
  • 328
  • 2
  • 11
m_rd_n
  • 175
  • 2
  • 11
0

As no other answer mentions the build in solution. Node Redis has a ping() function that returns PONG when executed.

const client = createClient( < CONNECTION_INFO> )

client.connect()

client.ping()
// PONG when healthy
-5

You can simply use sudo service redis-server status to check the current running status of redis on your local machine. Hope it helps.

magma
  • 131
  • 2
  • 8