Is there an easy way to run Garbage Collection outside of the request cycle in Passenger?

谁说我不能喝 提交于 2019-12-04 03:15:58

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!