开发者

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).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜