Class: Unicorn::OobGC

Inherits:
Struct
  • Object
show all
Defined in:
lib/unicorn/oob_gc.rb

Overview

Run GC after every request, after closing the client socket and before attempting to accept more connections.

This shouldn’t hurt overall performance as long as the server cluster is at <50% CPU capacity, and improves the performance of most memory intensive requests. This serves to improve client-visible performance (possibly at the cost of overall performance).

We’ll call GC after each request is been written out to the socket, so the client never sees the extra GC hit it.

This middleware is only effective for applications that use a lot of memory, and will hurt simpler apps/endpoints that can process multiple requests before incurring GC.

This middleware is only designed to work with Unicorn, as it harms keepalive performance.

Example (in config.ru):

require 'unicorn/oob_gc'

# GC ever two requests that hit /expensive/foo or /more_expensive/foo
# in your app.  By default, this will GC once every 5 requests
# for all endpoints in your app
use Unicorn::OobGC, 2, %r{\A/(?:expensive/foo|more_expensive/foo)}

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(app, interval = 5, path = %r{\A/}) ⇒ OobGC

Returns a new instance of OobGC.



32
33
34
# File 'lib/unicorn/oob_gc.rb', line 32

def initialize(app, interval = 5, path = %r{\A/})
  super(app, interval, path, interval)
end

Instance Attribute Details

#appObject

Returns the value of attribute app

Returns:

  • (Object)

    the current value of app



30
31
32
# File 'lib/unicorn/oob_gc.rb', line 30

def app
  @app
end

#bodyObject

Returns the value of attribute body

Returns:

  • (Object)

    the current value of body



30
31
32
# File 'lib/unicorn/oob_gc.rb', line 30

def body
  @body
end

#envObject

Returns the value of attribute env

Returns:

  • (Object)

    the current value of env



30
31
32
# File 'lib/unicorn/oob_gc.rb', line 30

def env
  @env
end

#intervalObject

Returns the value of attribute interval

Returns:

  • (Object)

    the current value of interval



30
31
32
# File 'lib/unicorn/oob_gc.rb', line 30

def interval
  @interval
end

#nrObject

Returns the value of attribute nr

Returns:

  • (Object)

    the current value of nr



30
31
32
# File 'lib/unicorn/oob_gc.rb', line 30

def nr
  @nr
end

#pathObject

Returns the value of attribute path

Returns:

  • (Object)

    the current value of path



30
31
32
# File 'lib/unicorn/oob_gc.rb', line 30

def path
  @path
end

Instance Method Details

#call(env) ⇒ Object



36
37
38
39
# File 'lib/unicorn/oob_gc.rb', line 36

def call(env)
  status, headers, self.body = app.call(self.env = env)
  [ status, headers, self ]
end

#closeObject

in Unicorn, this is closed after the client socket



46
47
48
49
50
51
52
53
54
55
# File 'lib/unicorn/oob_gc.rb', line 46

def close
  body.close if body.respond_to?(:close)

  if path =~ env['PATH_INFO'] && ((self.nr -= 1) <= 0)
    self.nr = interval
    self.body = nil
    env.clear
    GC.start
  end
end

#each(&block) ⇒ Object



41
42
43
# File 'lib/unicorn/oob_gc.rb', line 41

def each(&block)
  body.each(&block)
end