Is there an easy way to run Garbage Collection outside of the request cycle in Passenger?
Unicorn has OobGC rack middleware that can be used to run 开发者_C百科GC.start
after a certain number of requests.
Is there a similar sort of thing in Phusion Passenger?
Phusion Passenger 4 officially introduces an out of band garbage collection mechanism. It's more flexible than Unicorn's by allowing any arbitrary work, not just garbage collection. http://blog.phusion.nl/2013/01/22/phusion-passenger-4-technology-preview-out-of-band-work/
Hooking into PhusionPassenger::Rack::RequestHandler#process_request()
is the only mechanism I have found.
To do this in a similar way to the Unicorn OobGC, you can use the following module:
module PassengerOobGC
def self.install!(path, interval = 5)
self.const_set :OOBGC_PATH, path
self.const_set :OOBGC_INTERVAL, interval
@@oob_nr = interval
PhusionPassenger::Rack::RequestHandler.send :include, self
end
def self.included(base)
base.send :alias_method_chain, :process_request, :gc
end
def process_request_with_gc(env, *args)
process_request_without_gc(env, *args)
if OOBGC_PATH =~ env["PATH_INFO"] && ((@@oob_nr -= 1) <= 0)
@@oob_nr = OOBGC_INTERVAL
GC.start
end
end
end
and invoke it in an initializer with:
if defined?(PhusionPassenger::Rack::RequestHandler)
require 'passenger_oob_gc'
PassengerOobGC.install!(%r{^/admin/}, 3)
end
You have to patch Passenger. Doing a GC.start
after each request has been handed off ensures that garbage collection never occurs while holding a client request. This is a one-line change that you might consider if you're trying to reduce your average request time.
In lib/phusion_passenger/abstract_request_handler.rb, patch accept_and_process_next_request
and add the GC.start
call at the end, with an appropriate interval.
See this commit for an example (thanks, @raphaelcm).
精彩评论