我正在开发一个Rails应用程序,它使用Juggernaut定期向客户端推送数据。我使用控制器操作来启动推送;但由于推送通常是一个很长的过程(10分钟或更长时间),所以我使用spawn来分叉任务。例如:
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连接?
如果您对我所描述的内容有任何疑问,请告诉我。我很感谢你的帮助,因为我现在被困住了。
发布于 2012-10-04 21:46:23
问题是使用了全局变量(以$开头的变量)和Passenger。所有全局变量在所有乘客进程之间共享。Redis有某种类型的检查,以确保redis调用的进程ID与连接的进程ID相同。因此,如果redis是使用passenger worker 1连接的,但随后worker 2使用了它,则会出现此错误。
有关更多信息,请参见Redis::Client类的方法connect和ensure_connected。
在this issue中对解决方案进行了说明。基本上,他们建议您确实喜欢memcache作为explained here。
简而言之,在您的config/environement.rb .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
endhttps://stackoverflow.com/questions/11262067
复制相似问题