Class: Stalin::Adapter::Rack
- Inherits:
-
Object
- Object
- Stalin::Adapter::Rack
- Defined in:
- lib/stalin/adapter/rack.rb
Overview
A low-tech but reliable solution that invokes stalin using Rack middleware. This is suitable for application srvers that use a master-and-workers process architecture, wohse workers respond to a graceful shutdown signal, and whose masters spawn new workers as needed.
This functions as a base class for server-specific middlewares, and can be used if there is an app server that uses a signalling strategy not explicitly supported by Stalin.
Constant Summary collapse
- MB =
Conversion constant for human-readable memory amounts in log messages.
Float(1024**2)
Class Method Summary collapse
-
.new(*args) ⇒ Object
Construct a new middleware.
Instance Method Summary collapse
- #call(env) ⇒ Object
-
#initialize(app, graceful, abrupt, min = 1024**3, max = 2*1024**3, cycle = 16, verbose = false) ⇒ Rack
constructor
Create a middleware instance.
Constructor Details
#initialize(app, graceful, abrupt, min = 1024**3, max = 2*1024**3, cycle = 16, verbose = false) ⇒ Rack
Create a middleware instance.
51 52 53 54 55 56 57 58 59 |
# File 'lib/stalin/adapter/rack.rb', line 51 def initialize(app, graceful, abrupt, min=1024**3, max=2*1024**3, cycle=16, verbose=false) @app = app @graceful = graceful @abrupt = abrupt @min = min @max = max @cycle = cycle @verbose = verbose end |
Class Method Details
.new(*args) ⇒ Object
Construct a new middleware. If all six arguments are passed, construct an instance of this class; otherwise, use a heuristic to construct an instance of a suitable derived class.
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/stalin/adapter/rack.rb', line 19 def self.new(*args) if self == Rack && args.length < 3 # Warn that this shim will go away in v1 warn "Stalin::Adapter::Rack.new with fewer than 3 arguments is deprecated; please instantiate a derived class e.g. Unicorn or Puma" # Use a heuristic to decide on the correct adapter and instantiate a derived class. if defined?(::Unicorn) middleware = Unicorn.allocate elsif defined?(::Puma) middleware = Puma.allocate else raise RuntimeError, "Cannot determine a suitable Stalin adapter; please instantiate this class with six arguments" end # Initialize our new object (ugh) middleware.instance_eval { initialize(*args) } middleware else super end end |
Instance Method Details
#call(env) ⇒ Object
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/stalin/adapter/rack.rb', line 61 def call(env) result = @app.call(env) logger = logger_for(env) begin @lim ||= @min + randomize(@max - @min + 1) @req ||= 0 @req += 1 if @req % @cycle == 0 @req = 0 @watcher ||= ::Stalin::Watcher.new(Process.pid) @killer ||= ::Stalin::Killer.new(Process.pid, @graceful, @abrupt) if (used = @watcher.watch) > @lim sig = @killer.kill @watcher.watch logger.info "stalin (pid: %d) send SIG%s; memory usage %.1f MB > %.1f MB" % [Process.pid, sig, used / MB, @lim / MB] @cycle = 2 elsif @verbose logger.info "stalin (pid: %d) soldiers on; memory usage %.1f MB < %.1f MB" % [Process.pid, used / MB, @lim / MB] end end rescue Exception => e logger.error "stalin (pid: %d) ERROR %s: %s (%s)" % [Process.pid, e.class.name, e., e.backtrace.first] end result end |