Сценарий Node.js должен подождать, пока служба не запустится - PullRequest
1 голос
/ 16 октября 2011

У меня есть скрипт node.js, который запускается при загрузке.Он использует node-redis для создания клиента для Redis, но при загрузке Redis не готов, пока узел уже запускается.Таким образом, он выдает исключение и прекращает выполнение.

Первая часть выглядит следующим образом:

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

// Continue using runner

Исключение выдается в строке 3 (redis.createClient()).

Мое решение состояло в том, чтобы сделать бесконечный цикл, создать клиента в try / catch и, в случае успеха, остановить цикл:

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

Через пару секунд это будет вывод:

FATAL ERROR: JS Allocation failed - process out of memory

Как я могу решить это?Я ищу решение, которое может быть в php:

while (true) {
    $client = createClient($redis, $jobs, $queue);
    if ($client instanceof MyClient) break;
    else sleep(1);
}

1 Ответ

3 голосов
/ 16 октября 2011

setTimeout является асинхронным . В JavaScript (и Node.js) очень мало функций, которые ждут, чтобы что-то произошло, прежде чем продолжить (например, sleep). Вместо этого выполнение сразу продолжается до следующей строки, но вы передаете setTimeout функцию обратного вызова, которая запускается при ее запуске.

Я бы сделал что-то вроде этого (предупреждение, не проверено):

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
});
...