2012-06-29 45 views
0

我正在使用一個Rails應用程序,它使用Juggernaut來定期向客戶端推送數據。我使用控制器操作來啓動推送;但由於推送往往是一個漫長的過程(10分鐘或更長),我正在使用產卵來完成任務。例如:Rails應用程序:分叉後重新連接juggernaut redis?

def start_pushing 
    spawn_block(:argv => "juggernaut-pushing") do 
    for x in y 
     Juggernaut.publish(stuff in here) 
     sleep(30) # delay before publishing next item 
    end 
    end 
end 

的問題是,我發現在日誌文件中這個錯誤時,我打了start_pushing行動:

spawn> Exception in child[27898] - Redis::InheritedError: Tried to use a connection from a child process without reconnecting. You need to reconnect to Redis after forking. 

所以我增加了以下權利spawn_block裏,希望它能修復問題:

require 'redis' 
    $redis.client.disconnect 
    $redis = Redis.new(:host => 'localhost', :port => 6379) 

它似乎沒有解決這個問題,雖然行動一直斷斷續續甚至在我加入這個重置$ redis的。我在想,也許重置$ redis並沒有做任何事情; Juggernaut仍在訪問舊的連接。這看起來可能嗎?我如何確保Juggernaut使用新的Redis連接?

請讓我知道我所描述的任何問題。我很感激幫助,因爲我現在被卡住了。

回答

0

問題是使用全局(以$開頭的變量)並使用Passenger。所有乘客流程都共享所有全局變量。 Redis有一些檢查來確保redis調用的進程ID與連接的進程ID相同。因此,如果使用乘客1連接Redis,然後工作人員2使用它,則會出現此錯誤。

有關更多信息,請參閱Redis :: Client類的connect和ensure_connected方法。

該解決方案在this issue中進行了說明。 基本上,他們建議你像memcache那樣做explained here

總之,在你的config/environement.rb,添加以下內容:

if defined?(PhusionPassenger) 
    PhusionPassenger.on_event(:starting_worker_process) do |forked| 
     if forked 
      # We're in smart spawning mode. 
      $redis.reconnect 
     else 
      # We're in conservative spawning mode. We don't need to do anything. 
     end 
    end 
end 
相關問題