stalin 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/AUTHORS +4 -0
- data/CHANGELOG.md +2 -0
- data/LICENSE +93 -0
- data/README.md +48 -0
- data/Rakefile +19 -0
- data/VERSION +1 -0
- data/lib/stalin.rb +10 -0
- data/lib/stalin/adapter.rb +7 -0
- data/lib/stalin/adapter/rack.rb +67 -0
- data/lib/stalin/killer.rb +33 -0
- data/lib/stalin/watcher.rb +22 -0
- data/lib/stalin/watcher/linux_proc_statm.rb +30 -0
- data/lib/stalin/watcher/unix_ps.rb +33 -0
- data/stalin.gemspec +63 -0
- metadata +115 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 1895ae07adb3fd17811e68a5762343a42a424c55
|
4
|
+
data.tar.gz: d703399879596243653ed8d4b2a1380fdbc64890
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: fec5772f43ae44d775b5fce828f47d64555423eb2f271bcee8a006af8aeb0c53127b6d1091b840e85442c393d7cb41f4cc65aad7a363c7e1dfcfc4bf11736948
|
7
|
+
data.tar.gz: 1753c88baab75f9e0a77f1427b00f2f0d3194b973fcde1886f1d3eb4ef7d67ba7d68716d8e15595dc0696a2f4b9855d136c99d671e72623da501b95f6269bc7b
|
data/AUTHORS
ADDED
data/CHANGELOG.md
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
===== Stalin License
|
2
|
+
|
3
|
+
Copyright (c) 2015 Tony Spataro
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
'Software'), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
19
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
20
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
21
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
22
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
23
|
+
|
24
|
+
Stalin is derived from https://github.com/kzk/unicorn-worker-killer
|
25
|
+
including some code which was copied verbatim. The licensing
|
26
|
+
information for unicorn-worker-killer is reproduced below.
|
27
|
+
|
28
|
+
===== unicorn-worker-killer license
|
29
|
+
|
30
|
+
Unicorn is copyrighted free software by all contributors, see logs in
|
31
|
+
revision control for names and email addresses of all of them.
|
32
|
+
|
33
|
+
You can redistribute it and/or modify it under either the terms of the
|
34
|
+
GNU General Public License (GPL) as published by the Free Software
|
35
|
+
Foundation (FSF), version {3.0}[http://www.gnu.org/licenses/gpl-3.0.txt]
|
36
|
+
or version {2.0}[http://www.gnu.org/licenses/gpl-2.0.txt]
|
37
|
+
or the Ruby-specific license terms (see below).
|
38
|
+
|
39
|
+
The unicorn project leader (Eric Wong) reserves the right to add future
|
40
|
+
versions of the GPL (and no other licenses) as published by the FSF to
|
41
|
+
the licensing terms.
|
42
|
+
|
43
|
+
=== Ruby-specific terms (if you're not using the GPLv2 or GPLv3)
|
44
|
+
|
45
|
+
1. You may make and give away verbatim copies of the source form of the
|
46
|
+
software without restriction, provided that you duplicate all of the
|
47
|
+
original copyright notices and associated disclaimers.
|
48
|
+
|
49
|
+
2. You may modify your copy of the software in any way, provided that
|
50
|
+
you do at least ONE of the following:
|
51
|
+
|
52
|
+
a) place your modifications in the Public Domain or otherwise make them
|
53
|
+
Freely Available, such as by posting said modifications to Usenet or an
|
54
|
+
equivalent medium, or by allowing the author to include your
|
55
|
+
modifications in the software.
|
56
|
+
|
57
|
+
b) use the modified software only within your corporation or
|
58
|
+
organization.
|
59
|
+
|
60
|
+
c) rename any non-standard executables so the names do not conflict with
|
61
|
+
standard executables, which must also be provided.
|
62
|
+
|
63
|
+
d) make other distribution arrangements with the author.
|
64
|
+
|
65
|
+
3. You may distribute the software in object code or executable
|
66
|
+
form, provided that you do at least ONE of the following:
|
67
|
+
|
68
|
+
a) distribute the executables and library files of the software,
|
69
|
+
together with instructions (in the manual page or equivalent) on where
|
70
|
+
to get the original distribution.
|
71
|
+
|
72
|
+
b) accompany the distribution with the machine-readable source of the
|
73
|
+
software.
|
74
|
+
|
75
|
+
c) give non-standard executables non-standard names, with
|
76
|
+
instructions on where to get the original software distribution.
|
77
|
+
|
78
|
+
d) make other distribution arrangements with the author.
|
79
|
+
|
80
|
+
4. You may modify and include the part of the software into any other
|
81
|
+
software (possibly commercial). But some files in the distribution
|
82
|
+
are not written by the author, so that they are not under this terms.
|
83
|
+
|
84
|
+
5. The scripts and library files supplied as input to or produced as
|
85
|
+
output from the software do not automatically fall under the
|
86
|
+
copyright of the software, but belong to whomever generated them,
|
87
|
+
and may be sold commercially, and may be aggregated with this
|
88
|
+
software.
|
89
|
+
|
90
|
+
6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
|
91
|
+
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
92
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
93
|
+
PURPOSE.
|
data/README.md
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
# stalin
|
2
|
+
|
3
|
+
Given Ruby's proclivity for heap fragmentation, Web application worker processes tend to exhaust
|
4
|
+
all available memory unless the server is restarted periodically. When all of the workers restart
|
5
|
+
at once, downtime or bad request throughput may result.
|
6
|
+
|
7
|
+
Stalin is a gem that gradually kills your workers before they cause swapping, resulting in better
|
8
|
+
availability for your application. Its design goals are modularity and compatibility with a range
|
9
|
+
of platforms and app servers.
|
10
|
+
|
11
|
+
Metrics include:
|
12
|
+
- Resident Set Size (RSS)
|
13
|
+
|
14
|
+
Data sources include:
|
15
|
+
- Linux ProcFS
|
16
|
+
- Generic ps
|
17
|
+
|
18
|
+
Supported app servers include:
|
19
|
+
- Rainbows (via Rack middleware + SIGQUIT)
|
20
|
+
- Unicorn (via Rack middleware + SIGQUIT)
|
21
|
+
|
22
|
+
(As you can see, we are far short of our _goal_ to support many servers! More to come as needed;
|
23
|
+
I'm happy to take your contributions.)
|
24
|
+
|
25
|
+
# Installation
|
26
|
+
|
27
|
+
Just include stalin in your Gemfile.
|
28
|
+
|
29
|
+
gem 'stalin'
|
30
|
+
|
31
|
+
# Usage
|
32
|
+
|
33
|
+
Add these lines near the top of your `config.ru`
|
34
|
+
|
35
|
+
# Unicorn self-process killer
|
36
|
+
require 'stalin'
|
37
|
+
|
38
|
+
# Max memory size (RSS) per worker
|
39
|
+
mb = 1024**2
|
40
|
+
use Stalin::Adapter::Rack, (192*mb), (256*mb)
|
41
|
+
|
42
|
+
# Tuning
|
43
|
+
|
44
|
+
TODO
|
45
|
+
|
46
|
+
# Special Thanks
|
47
|
+
|
48
|
+
- [@kzk](http://github.com/kzk/) for the [unicorn-worker-killer] gem which this is derived from
|
data/Rakefile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
|
3
|
+
require 'jeweler'
|
4
|
+
Jeweler::Tasks.new do |gem|
|
5
|
+
gem.name = "stalin"
|
6
|
+
gem.homepage = "https://github.com/xeger/stalin"
|
7
|
+
gem.license = "MIT"
|
8
|
+
gem.summary = %Q{Kill rack }
|
9
|
+
gem.description = %Q{Kill Web application workers based on arbitrary conditions.}
|
10
|
+
gem.email = "xeger@xeger.net"
|
11
|
+
gem.authors = ["Tony Spataro"]
|
12
|
+
gem.files.exclude ".rspec"
|
13
|
+
gem.files.exclude "Gemfile*"
|
14
|
+
gem.files.exclude "fixtures/**/*"
|
15
|
+
gem.files.exclude "spec/**/*"
|
16
|
+
end
|
17
|
+
Jeweler::RubygemsDotOrgTasks.new
|
18
|
+
|
19
|
+
CLEAN.include('pkg')
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.2
|
data/lib/stalin.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
module Stalin::Adapter
|
2
|
+
# A low-tech but reliable solution that invokes stalin using Rack middleware.
|
3
|
+
# This is suitable for servers that handle SIGQUIT gracefully and spawn new
|
4
|
+
# worker processes as needed.
|
5
|
+
class Rack
|
6
|
+
# Conversion constant for human-readable memory amounts in log messages.
|
7
|
+
MB = Float(1024**2)
|
8
|
+
|
9
|
+
# Create a middleware instance.
|
10
|
+
#
|
11
|
+
# @param [#call] app
|
12
|
+
# @param [Integer] min lower-bound worker memory consumption before restart
|
13
|
+
# @param [Integer] max upper-bound worker memory consumption before restart
|
14
|
+
# @param [Integer] cycle how frequently to check memory consumption (# requests)
|
15
|
+
# @param [Boolean] verbose log extra information
|
16
|
+
def initialize(app, min=1024**3, max=2*1024**3, cycle=16, verbose=false)
|
17
|
+
@app = app
|
18
|
+
@min = min
|
19
|
+
@max = max
|
20
|
+
@cycle = cycle
|
21
|
+
@verbose = verbose
|
22
|
+
end
|
23
|
+
|
24
|
+
def call(env)
|
25
|
+
result = @app.call(env)
|
26
|
+
|
27
|
+
logger = logger_for(env)
|
28
|
+
|
29
|
+
begin
|
30
|
+
@lim ||= @min + randomize(@max - @min + 1)
|
31
|
+
@req ||= 0
|
32
|
+
@req += 1
|
33
|
+
|
34
|
+
if @req % @cycle == 0
|
35
|
+
@req = 0
|
36
|
+
@watcher ||= ::Stalin::Watcher.new(Process.pid)
|
37
|
+
@killer ||= ::Stalin::Killer.new(Process.pid)
|
38
|
+
if (used = @watcher.watch) > @lim
|
39
|
+
sig = @killer.kill
|
40
|
+
@watcher.watch
|
41
|
+
logger.info "stalin (pid: %d) send SIG%s; memory usage %.1f MB > %.1f MB" %
|
42
|
+
[Process.pid, sig, used / MB, @lim / MB]
|
43
|
+
@cycle = 2
|
44
|
+
elsif @verbose
|
45
|
+
logger.info "stalin (pid: %d) soldiers on; memory usage %.1f MB < %.1f MB" %
|
46
|
+
[Process.pid, used / MB, @lim / MB]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
rescue Exception => e
|
50
|
+
logger.error "stalin (pid: %d) ERROR %s: %s (%s)" %
|
51
|
+
[Process.pid, e.class.name, e.message, e.backtrace.first]
|
52
|
+
end
|
53
|
+
|
54
|
+
result
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def randomize(integer)
|
60
|
+
RUBY_VERSION > "1.9" ? Random.rand(integer.abs) : rand(integer)
|
61
|
+
end
|
62
|
+
|
63
|
+
def logger_for(env)
|
64
|
+
env['rack.logger'] || (@logger ||= Logger.new(STDERR))
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Stalin
|
2
|
+
# Kill a process by sending SIGQUIT several times, then SIGTERM, and finally SIGKILL.
|
3
|
+
class Killer
|
4
|
+
# Number of cumulative tries to send SIGQUIT before we escalate to SIGTERM
|
5
|
+
MAX_QUIT = 10
|
6
|
+
# Number of cumulative tries before we escalate to SIGKILL
|
7
|
+
MAX_TERM = 15
|
8
|
+
|
9
|
+
# @param [Integer] pid target process ID
|
10
|
+
def initialize(pid)
|
11
|
+
@pid = pid
|
12
|
+
@tries = 0
|
13
|
+
end
|
14
|
+
|
15
|
+
# Try to kill the target process by sending it a shutdown signal.
|
16
|
+
#
|
17
|
+
# @return [:QUIT,:TERM,:KILL] name of signal that we sent
|
18
|
+
def kill
|
19
|
+
case @tries
|
20
|
+
when (0...MAX_QUIT)
|
21
|
+
sig = :QUIT
|
22
|
+
when (MAX_QUIT...MAX_TERM)
|
23
|
+
sig = :TERM
|
24
|
+
else
|
25
|
+
sig = :KILL
|
26
|
+
end
|
27
|
+
|
28
|
+
@tries += 1
|
29
|
+
Process.kill(sig, @pid)
|
30
|
+
sig
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Stalin
|
2
|
+
module Watcher
|
3
|
+
def self.new(pid)
|
4
|
+
it = nil
|
5
|
+
|
6
|
+
constants.each do |konst|
|
7
|
+
begin
|
8
|
+
konst = const_get(konst)
|
9
|
+
it = konst.new(pid)
|
10
|
+
break
|
11
|
+
rescue Stalin::Unsupported
|
12
|
+
next
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
it || raise(Stalin::Unsupported, "No compatible Watcher was found among #{constants}")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
require 'stalin/watcher/linux_proc_statm'
|
22
|
+
require 'stalin/watcher/unix_ps'
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Stalin::Watcher
|
2
|
+
# Watcher that uses procfs (specifically /proc/<pid>/statm) to determine memory usage.
|
3
|
+
class LinuxProcStatm
|
4
|
+
# @raise [Stalin::Unsupported] if watcher cannot be instantiated on current platform
|
5
|
+
# @param [Integer] pid target process ID
|
6
|
+
def initialize(pid)
|
7
|
+
@statm = "/proc/%d/statm" % [pid]
|
8
|
+
raise Stalin::Unsupported, "Unreadable or nonexistent file: #{@statm}" unless File.readable?(@statm)
|
9
|
+
|
10
|
+
page_size = `getconf PAGESIZE`
|
11
|
+
@page_size = Integer(page_size) rescue nil
|
12
|
+
raise Stalin::Unsupported, "Cannot determine page size: #{page_size}" unless $?.success? && @page_size.kind_of?(Integer)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Report on memory usage.
|
16
|
+
#
|
17
|
+
# @return [Integer,nil] target process' memory usage in bytes, nil if process not found
|
18
|
+
def watch
|
19
|
+
vsz, rss, shared = File.read(@statm).split(' ')
|
20
|
+
vsz = Integer(vsz) * @page_size
|
21
|
+
rss = Integer(rss) * @page_size
|
22
|
+
shared = Integer(shared) * @page_size
|
23
|
+
|
24
|
+
rss
|
25
|
+
rescue SystemCallError
|
26
|
+
# assume any failure means that process has gone away
|
27
|
+
nil
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Stalin::Watcher
|
2
|
+
class UnixPs
|
3
|
+
# @raise [Stalin::Unsupported] if watcher cannot be instantiated on current platform
|
4
|
+
# @param [Integer] pid target process ID
|
5
|
+
def initialize(pid)
|
6
|
+
begin
|
7
|
+
ps(Process.pid)
|
8
|
+
rescue StandardError => e
|
9
|
+
raise Stalin::Unsupported, "ps failed: #{e.message}"
|
10
|
+
end
|
11
|
+
|
12
|
+
@pid = pid
|
13
|
+
end
|
14
|
+
|
15
|
+
# Report on memory usage.
|
16
|
+
#
|
17
|
+
# @return [Integer,nil] target process' memory usage in bytes, nil if process not found
|
18
|
+
def watch
|
19
|
+
ps(@pid)
|
20
|
+
rescue ArgumentError
|
21
|
+
nil
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
# Report on memory usage.
|
27
|
+
#
|
28
|
+
# @return [Integer] target process' memory usage in bytes
|
29
|
+
def ps(pid)
|
30
|
+
Integer(`#{"ps -o rss= -p %d" % [pid]}`) * 1024
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/stalin.gemspec
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
# stub: stalin 0.0.2 ruby lib
|
6
|
+
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = "stalin"
|
9
|
+
s.version = "0.0.2"
|
10
|
+
|
11
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
|
+
s.require_paths = ["lib"]
|
13
|
+
s.authors = ["Tony Spataro"]
|
14
|
+
s.date = "2015-02-10"
|
15
|
+
s.description = "Kill Web application workers based on arbitrary conditions."
|
16
|
+
s.email = "xeger@xeger.net"
|
17
|
+
s.extra_rdoc_files = [
|
18
|
+
"LICENSE",
|
19
|
+
"README.md"
|
20
|
+
]
|
21
|
+
s.files = [
|
22
|
+
"AUTHORS",
|
23
|
+
"CHANGELOG.md",
|
24
|
+
"LICENSE",
|
25
|
+
"README.md",
|
26
|
+
"Rakefile",
|
27
|
+
"VERSION",
|
28
|
+
"lib/stalin.rb",
|
29
|
+
"lib/stalin/adapter.rb",
|
30
|
+
"lib/stalin/adapter/rack.rb",
|
31
|
+
"lib/stalin/killer.rb",
|
32
|
+
"lib/stalin/watcher.rb",
|
33
|
+
"lib/stalin/watcher/linux_proc_statm.rb",
|
34
|
+
"lib/stalin/watcher/unix_ps.rb",
|
35
|
+
"stalin.gemspec"
|
36
|
+
]
|
37
|
+
s.homepage = "https://github.com/xeger/stalin"
|
38
|
+
s.licenses = ["MIT"]
|
39
|
+
s.rubygems_version = "2.2.2"
|
40
|
+
s.summary = "Kill rack"
|
41
|
+
|
42
|
+
if s.respond_to? :specification_version then
|
43
|
+
s.specification_version = 4
|
44
|
+
|
45
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
46
|
+
s.add_development_dependency(%q<jeweler>, ["~> 2.0"])
|
47
|
+
s.add_development_dependency(%q<rspec>, ["~> 3.0"])
|
48
|
+
s.add_development_dependency(%q<sinatra>, ["~> 1.4"])
|
49
|
+
s.add_development_dependency(%q<unicorn>, ["~> 4.8"])
|
50
|
+
else
|
51
|
+
s.add_dependency(%q<jeweler>, ["~> 2.0"])
|
52
|
+
s.add_dependency(%q<rspec>, ["~> 3.0"])
|
53
|
+
s.add_dependency(%q<sinatra>, ["~> 1.4"])
|
54
|
+
s.add_dependency(%q<unicorn>, ["~> 4.8"])
|
55
|
+
end
|
56
|
+
else
|
57
|
+
s.add_dependency(%q<jeweler>, ["~> 2.0"])
|
58
|
+
s.add_dependency(%q<rspec>, ["~> 3.0"])
|
59
|
+
s.add_dependency(%q<sinatra>, ["~> 1.4"])
|
60
|
+
s.add_dependency(%q<unicorn>, ["~> 4.8"])
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
metadata
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: stalin
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Tony Spataro
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-02-12 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: jeweler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: sinatra
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.4'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.4'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: unicorn
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '4.8'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '4.8'
|
69
|
+
description: Kill Web application workers based on arbitrary conditions.
|
70
|
+
email: xeger@xeger.net
|
71
|
+
executables: []
|
72
|
+
extensions: []
|
73
|
+
extra_rdoc_files:
|
74
|
+
- LICENSE
|
75
|
+
- README.md
|
76
|
+
files:
|
77
|
+
- AUTHORS
|
78
|
+
- CHANGELOG.md
|
79
|
+
- LICENSE
|
80
|
+
- README.md
|
81
|
+
- Rakefile
|
82
|
+
- VERSION
|
83
|
+
- lib/stalin.rb
|
84
|
+
- lib/stalin/adapter.rb
|
85
|
+
- lib/stalin/adapter/rack.rb
|
86
|
+
- lib/stalin/killer.rb
|
87
|
+
- lib/stalin/watcher.rb
|
88
|
+
- lib/stalin/watcher/linux_proc_statm.rb
|
89
|
+
- lib/stalin/watcher/unix_ps.rb
|
90
|
+
- stalin.gemspec
|
91
|
+
homepage: https://github.com/xeger/stalin
|
92
|
+
licenses:
|
93
|
+
- MIT
|
94
|
+
metadata: {}
|
95
|
+
post_install_message:
|
96
|
+
rdoc_options: []
|
97
|
+
require_paths:
|
98
|
+
- lib
|
99
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
105
|
+
requirements:
|
106
|
+
- - ">="
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '0'
|
109
|
+
requirements: []
|
110
|
+
rubyforge_project:
|
111
|
+
rubygems_version: 2.2.2
|
112
|
+
signing_key:
|
113
|
+
specification_version: 4
|
114
|
+
summary: Kill rack
|
115
|
+
test_files: []
|