Using acts as ferret with phusion passenger / mod_rails
Categories rails, ruby | 2 March, 2009 | By Stephen Sykes
The passenger manual makes it clear that you need to close and reestablish your connections to things like memcached after it forks to avoid inadventently sharing file handles. The reason is well and clearly explained there.
The api to do this is simple – just place this kind of code in your environment.rb file:
PhusionPassenger.on_event(:starting_worker_process) do |forked|
if forked
# We’re in smart spawning mode.
– reestablish connections –
else
# We’re in conservative spawning mode. We don’t need to do anything.
end
end
end
All well and good, but how exactly do you reestablish those connections?
In our case we have to deal with memcached and ferret (with ferret running in a DRb server via the acts_as_ferret plugin).
Memcached is dead easy:
Ferret not so easy. It turns out that DRb has no in-built way to close its pool of connections. So a monkey patch is the only thing to do. I was inspired by some code you can find here. But since we want to blindly close all the connections, our case is simpler:
def self.close_all
@mutex.synchronize do
@pool.each {|c| c.close}
@pool = []
end
end
end
DRb::DRbConn.close_all
DRb will happily reconnect by itself when needed after its connection pool has been emptied.
Putting it all together, it looks like this:
# monkey patch drb so we can close its connections
class DRb::DRbConn
def self.close_all
@mutex.synchronize do
@pool.each {|c| c.close}
@pool = []
end
end
end
PhusionPassenger.on_event(:starting_worker_process) do |forked|
if forked
# We’re in smart spawning mode.
CACHE.reset # memcached
DRb::DRbConn.close_all # ferret
else
# We’re in conservative spawning mode. We don’t need to do anything.
end
end
end
RSS