alicorn 0.0.9 → 0.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/VERSION +1 -1
- data/alicorn.gemspec +2 -2
- data/bin/alicorn_profiler +3 -2
- data/lib/alicorn/scaler.rb +7 -6
- data/test/{test_alicorn.rb → test_scaler.rb} +17 -3
- metadata +16 -16
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.10
|
data/alicorn.gemspec
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "alicorn"
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.10"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Ben Somers"]
|
@@ -33,7 +33,7 @@ Gem::Specification.new do |s|
|
|
33
33
|
"lib/alicorn/log_parser.rb",
|
34
34
|
"lib/alicorn/scaler.rb",
|
35
35
|
"test/helper.rb",
|
36
|
-
"test/
|
36
|
+
"test/test_scaler.rb"
|
37
37
|
]
|
38
38
|
s.homepage = "http://github.com/bensomers/alicorn"
|
39
39
|
s.licenses = ["MIT"]
|
data/bin/alicorn_profiler
CHANGED
@@ -70,8 +70,9 @@ scaler = Alicorn::Scaler.new(@options)
|
|
70
70
|
|
71
71
|
p "Testing #{@alp.samples.count} samples"
|
72
72
|
@alp.samples.each do |sample|
|
73
|
-
|
74
|
-
|
73
|
+
connections = sample[:active].zip(sample[:queued]).map { |e| e.inject(:+) }
|
74
|
+
if connections.max > @worker_count
|
75
|
+
p "Overloaded! Ran #{@worker_count} and got #{connections.max} active + queued"
|
75
76
|
p sample if options[:verbose]
|
76
77
|
end
|
77
78
|
sig, count = scaler.send(:auto_scale, sample, @worker_count)
|
data/lib/alicorn/scaler.rb
CHANGED
@@ -8,8 +8,6 @@ module Alicorn
|
|
8
8
|
:raindrops_url, :delay, :sample_count, :app_name, :dry_run, :logger
|
9
9
|
|
10
10
|
def initialize(options = {})
|
11
|
-
raise ArgumentError.new("You must pass a :max_workers option") unless options[:max_workers]
|
12
|
-
|
13
11
|
self.min_workers = options[:min_workers] || 1
|
14
12
|
self.max_workers = options[:max_workers]
|
15
13
|
self.target_ratio = options[:target_ratio] || 1.3
|
@@ -28,6 +26,8 @@ module Alicorn
|
|
28
26
|
def scale!
|
29
27
|
data = collect_data
|
30
28
|
unicorns = find_unicorns
|
29
|
+
|
30
|
+
abort "Could not find any unicorn processes" if unicorns.empty?
|
31
31
|
master_pid = find_master_pid(unicorns)
|
32
32
|
worker_count = find_worker_count(unicorns)
|
33
33
|
|
@@ -43,10 +43,12 @@ module Alicorn
|
|
43
43
|
protected
|
44
44
|
|
45
45
|
def auto_scale(data, worker_count)
|
46
|
-
return nil if data[:active].empty?
|
46
|
+
return nil if data[:active].empty? or data[:queued].empty?
|
47
|
+
connections = data[:active].zip(data[:queued]).map { |e| e.inject(:+) }
|
48
|
+
connections = DataSet.new(connections)
|
47
49
|
|
48
50
|
# Calculate target
|
49
|
-
target =
|
51
|
+
target = connections.max * target_ratio + buffer
|
50
52
|
|
51
53
|
# Check hard thresholds
|
52
54
|
target = max_workers if max_workers and target > max_workers
|
@@ -54,7 +56,7 @@ module Alicorn
|
|
54
56
|
target = target.ceil
|
55
57
|
|
56
58
|
logger.debug "target calculated at: #{target}, worker count at #{worker_count}"
|
57
|
-
if
|
59
|
+
if connections.avg > worker_count and data[:queued].avg > 1
|
58
60
|
logger.debug "danger, will robinson! scaling up fast!"
|
59
61
|
return "TTIN", target - worker_count
|
60
62
|
elsif target > worker_count
|
@@ -90,7 +92,6 @@ module Alicorn
|
|
90
92
|
unicorns.map(&:strip)
|
91
93
|
end
|
92
94
|
|
93
|
-
|
94
95
|
def collect_data
|
95
96
|
logger.debug "Sampling #{sample_count} times"
|
96
97
|
calling, writing, active, queued = DataSet.new, DataSet.new, DataSet.new, DataSet.new
|
@@ -11,6 +11,17 @@ class TestScaler < Test::Unit::TestCase
|
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
+
context "#scale!" do
|
15
|
+
context "when no unicorn processes are running" do
|
16
|
+
end
|
17
|
+
context "when multiple master processes are found" do
|
18
|
+
end
|
19
|
+
context "when an old master process is running" do
|
20
|
+
end
|
21
|
+
context "when things are properly detected" do
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
14
25
|
context "#auto_scale" do
|
15
26
|
setup do
|
16
27
|
@scaler.publicize :auto_scale
|
@@ -21,12 +32,13 @@ class TestScaler < Test::Unit::TestCase
|
|
21
32
|
@scaler.target_ratio = 1.3
|
22
33
|
@data = { :active => DataSet.new,
|
23
34
|
:queued => DataSet.new }
|
24
|
-
@data[:queued]
|
35
|
+
@data[:queued]
|
25
36
|
end
|
26
37
|
|
27
38
|
context "when we're above the target" do
|
28
39
|
setup do
|
29
40
|
@data[:active] << 3 << 4 << 5
|
41
|
+
@data[:queued] << 0 << 0 << 0
|
30
42
|
end
|
31
43
|
|
32
44
|
should "return 1 TTOU" do
|
@@ -37,6 +49,7 @@ class TestScaler < Test::Unit::TestCase
|
|
37
49
|
context "when we're below the target" do
|
38
50
|
setup do
|
39
51
|
@data[:active] << 2 << 10
|
52
|
+
@data[:queued] << 0 << 0
|
40
53
|
end
|
41
54
|
|
42
55
|
should "return 1 TTIN" do
|
@@ -46,8 +59,8 @@ class TestScaler < Test::Unit::TestCase
|
|
46
59
|
|
47
60
|
context "when we need to scale up fast" do
|
48
61
|
setup do
|
49
|
-
@data[:queued] <<
|
50
|
-
@data[:active] <<
|
62
|
+
@data[:queued] << 6
|
63
|
+
@data[:active] << 6
|
51
64
|
end
|
52
65
|
|
53
66
|
should "return several TTIN" do
|
@@ -58,6 +71,7 @@ class TestScaler < Test::Unit::TestCase
|
|
58
71
|
context "when we don't need to scale at all" do
|
59
72
|
setup do
|
60
73
|
@data[:active] << 6
|
74
|
+
@data[:queued] << 0
|
61
75
|
end
|
62
76
|
|
63
77
|
should "return several TTIN" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: alicorn
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.10
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-05-
|
12
|
+
date: 2012-05-22 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: curb
|
16
|
-
requirement: &
|
16
|
+
requirement: &70103116675180 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 0.8.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70103116675180
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: shoulda
|
27
|
-
requirement: &
|
27
|
+
requirement: &70103116673500 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: 3.0.1
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70103116673500
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rdoc
|
38
|
-
requirement: &
|
38
|
+
requirement: &70103116672420 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '3.12'
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70103116672420
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: bundler
|
49
|
-
requirement: &
|
49
|
+
requirement: &70103116671500 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ~>
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: 1.1.3
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70103116671500
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: jeweler
|
60
|
-
requirement: &
|
60
|
+
requirement: &70103116670920 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ~>
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: 1.8.3
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *70103116670920
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: mocha
|
71
|
-
requirement: &
|
71
|
+
requirement: &70103116670380 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ~>
|
@@ -76,7 +76,7 @@ dependencies:
|
|
76
76
|
version: 0.11.4
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *70103116670380
|
80
80
|
description: Highly configurable dumb auto-scaler for managing unicorn web servers
|
81
81
|
email: somers.ben@gmail.com
|
82
82
|
executables:
|
@@ -102,7 +102,7 @@ files:
|
|
102
102
|
- lib/alicorn/log_parser.rb
|
103
103
|
- lib/alicorn/scaler.rb
|
104
104
|
- test/helper.rb
|
105
|
-
- test/
|
105
|
+
- test/test_scaler.rb
|
106
106
|
homepage: http://github.com/bensomers/alicorn
|
107
107
|
licenses:
|
108
108
|
- MIT
|
@@ -118,7 +118,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
118
118
|
version: '0'
|
119
119
|
segments:
|
120
120
|
- 0
|
121
|
-
hash: -
|
121
|
+
hash: -225078698717891469
|
122
122
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
123
123
|
none: false
|
124
124
|
requirements:
|