2013-11-14 20:15:37 -05:00
# Hook into unicorn, unicorn middleware, not rack middleware
#
# Since we need no knowledge about the request we can simply
# hook unicorn
module Middleware::UnicornOobgc
2013-11-15 01:17:08 -05:00
MIN_REQUESTS_PER_OOBGC = 5
MAX_DELTAS = 25
2013-11-14 20:15:37 -05:00
def self . init
# hook up HttpServer intercept
ObjectSpace . each_object ( Unicorn :: HttpServer ) do | s |
s . extend ( self )
end
2013-11-15 01:03:03 -05:00
rescue
puts " Attempted to patch Unicorn but it is not loaded "
2013-11-14 20:15:37 -05:00
end
def process_client ( client )
stat = GC . stat
@previous_deltas || = [ ]
@num_requests || = 0
@num_requests += 1
# only track N deltas
if @previous_deltas . length > MAX_DELTAS
@previous_deltas . delete_at ( 0 )
end
gc_count = stat [ :count ]
live_num = stat [ :heap_live_num ]
super ( client ) # Unicorn::HttpServer#process_client
# at this point client is serviced
stat = GC . stat
new_gc_count = stat [ :count ]
new_live_num = stat [ :heap_live_num ]
# no GC happened during the request
if new_gc_count == gc_count
@previous_deltas << ( new_live_num - live_num )
if @gc_live_num && @num_requests > MIN_REQUESTS_PER_OOBGC
largest = @previous_deltas . max
2013-11-15 01:17:08 -05:00
if ( largest * 3 ) + new_live_num > @gc_live_num
2013-11-15 01:54:29 -05:00
# While tuning consider printing this out, each time this happens you saved
# a user from running a GC inline
2013-11-15 02:22:02 -05:00
# t = Time.now
2013-11-14 20:15:37 -05:00
GC . start
2013-11-15 02:22:02 -05:00
# puts "OobGC invoked req count: #{@num_requests} largest delta: #{largest} #{((Time.now - t) * 1000).to_i}ms saved"
2013-11-14 20:15:37 -05:00
@num_requests = 0
end
end
else
2013-11-15 01:08:38 -05:00
puts " OobGC: GC live num adjusted: old live_num #{ @gc_live_num } new: #{ live_num } - reqs since GC: #{ @num_requests } largest delta: #{ @previous_deltas . max } "
2013-11-15 00:56:21 -05:00
@num_requests = 0
2013-11-14 20:15:37 -05:00
@gc_live_num = live_num
2013-11-15 00:56:21 -05:00
2013-11-14 20:15:37 -05:00
end
end
end