2011-10-16 32 views
1

我有一个node.js脚本,它在启动时启动。它使用node-redis为Redis创建客户端,但在引导时,Redis尚未准备好,而节点已经启动。所以,它会发出异常并停止执行。Node.js脚本应该在服务运行之前等待

第一部分看起来像这样:

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); 
} 
+0

如果两个启动服务有依存关系,做easyest的事情是确保在正确的顺序启动,我猜。 – Slartibartfast

回答

3

setTimeout异步。 JavaScript(和Node.js)只有很少的功能可以在继续之前等待某些事情发生(如sleep)。相反,执行会立即继续到下一行,但是您会传递一个回调函数,该函数在触发时运行。

我会做这样的事情(警告,未经测试):

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 
}); 
+0

这个面向方面的例子似乎比@ Fosco的一个好(对不起Fosco),我会很快将它标记为答案。 Atm,redis.createClient()中的异常不会被我的try/catch捕获。当我明白这一点时,我会给你信贷。 –

+0

@JurianSluiman没有问题,删除了我的,因为它证明不是一个正确的答案。我正在用process.nexttick思考一个解决方案,但没有得到解决。 – Fosco

+0

@Sidnicious,我假设你想写'setTimeout(createClient,1000);'?因为这是错的,如果第一次尝试失败,它会在成功之前回调。它甚至会不止一次地回电! – thejh

相关问题