Get Even More Visitors To Your Blog, Upgrade To A Business Listing >>

Node.js script should wait before service is running

Node.js script should wait before service is running

Problem

I have a node.js script which starts at boot. It uses node-redis to create a client for Redis, but at boot Redis is not ready while node is already starting. So, it gives an exception and stops executing.

The first part looks like this:

var redis  = require("redis"),
    jobs   = require("jobs"),
    client = redis.createClient(),
    runner = new jobs(client, "job-queue",{});

// Continue using runner

The exception is thrown in line 3 (redis.createClient()).

My solution was to make an endless loop, create the client in a try/catch and when successful, stop the loop:

var redis  = require("redis"),
    jobs   = require("jobs"),
    queue  = 'job-queue',
    client = null,
    runner = null,
    createClient = function (redis, jobs, queue) {
        try {
            client = redis.createClient();
            return new jobs(client, queue, {});
        } catch (err) {
            return null;
        }
    };

while(true) {
    setTimeout(function() {
        runner = createClient(redis, jobs, queue);
    }, 1000);

    if (null !== runner) break;
}

// Continue using runner

After a couple of seconds, this is the output:

FATAL ERROR: JS Allocation failed - process out of memory

How can I solve this? I am searching for a solution which could be in php:

while (true) {
    $client = createClient($redis, $jobs, $queue);
    if ($client instanceof MyClient) break;
    else sleep(1);
}
Problem courtesy of: Jurian Sluiman

Solution

setTimeout is asynchronous. JavaScript (and Node.js) have very few functions that wait for something to happen before continuing (like sleep). Instead, execution continues to the next line right away, but you pass setTimeout a callback function which is run when it fires.

I would do something like this (warning, untested):

var redis  = require("redis"),
    jobs   = require("jobs"),
    queue  = 'job-queue';

function initializeRedis(callback) {
    (function createClient(){
        var runner;
        try {
            client = redis.createClient();
            runner = new jobs(client, queue, {});
        } catch (e) {}
        if (runner){
            callback(runner);
        } else {
            setTimeout(createClient, 1000);
        }
    })();
};

initializeRedis(function(runner){
    // Continue using runner
});
Solution courtesy of: s4y

Discussion

View additional discussion.



This post first appeared on Node.js Recipes, please read the originial post: here

Share the post

Node.js script should wait before service is running

×

Subscribe to Node.js Recipes

Get updates delivered right to your inbox!

Thank you for your subscription

×