2011-10-16 33 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

相關問題