our-eel-hacks 0.0.15 → 0.0.16
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/lib/our-eel-hacks/autoscaler.rb +7 -8
- data/lib/our-eel-hacks/rack.rb +7 -7
- data/lib/our-eel-hacks/sidekiq.rb +3 -3
- data/spec/autoscaler.rb +22 -7
- data/spec/rack.rb +2 -1
- data/spec_help/spec_helper.rb +17 -0
- metadata +8 -8
@@ -1,4 +1,4 @@
|
|
1
|
-
require 'heroku'
|
1
|
+
require 'our-eel-hacks/heroku-client'
|
2
2
|
|
3
3
|
module OurEelHacks
|
4
4
|
class NullLogger
|
@@ -132,8 +132,11 @@ module OurEelHacks
|
|
132
132
|
end
|
133
133
|
|
134
134
|
API_CALLS_PER_SCALE = 2
|
135
|
-
def scale(
|
136
|
-
logger.debug{ "Scaling request for #{@ps_type}:
|
135
|
+
def scale(metric_hash)
|
136
|
+
logger.debug{ "Scaling request for #{@ps_type}: metrics are: #{metric_hash.inspect}" }
|
137
|
+
|
138
|
+
#TODO: multi-metric scaling logic
|
139
|
+
metric = metric_hash.to_a.last.last #Yeah, this is awful
|
137
140
|
moment = Time.now
|
138
141
|
if elapsed(last_scaled, moment) < millis_til_next_scale
|
139
142
|
logger.debug{ "Not scaling: elapsed #{elapsed(last_scaled, moment)} less than computed #{millis_til_next_scale}" }
|
@@ -232,11 +235,7 @@ module OurEelHacks
|
|
232
235
|
end
|
233
236
|
|
234
237
|
def heroku
|
235
|
-
@heroku ||=
|
236
|
-
unless client.info(app_name)[:stack] == "cedar"
|
237
|
-
raise "#{self.class.name} built against cedar stack"
|
238
|
-
end
|
239
|
-
end
|
238
|
+
@heroku ||= HerokuClient.new(logger, "", heroku_api_key)
|
240
239
|
end
|
241
240
|
|
242
241
|
def set_dynos(count,moment)
|
data/lib/our-eel-hacks/rack.rb
CHANGED
@@ -4,15 +4,15 @@ module OurEelHacks
|
|
4
4
|
class Rack < Middleware
|
5
5
|
include Defer::EventMachine
|
6
6
|
|
7
|
-
def initialize(app,
|
7
|
+
def initialize(app, env_fields, flavor = :web)
|
8
8
|
super(flavor)
|
9
|
-
@
|
9
|
+
@env_fields = [*env_fields].map(&:to_s)
|
10
10
|
@app = app
|
11
11
|
end
|
12
12
|
|
13
13
|
def call(env)
|
14
14
|
begin
|
15
|
-
autoscale(
|
15
|
+
autoscale(metrics_from(env))
|
16
16
|
rescue => ex
|
17
17
|
puts "Problem in autoscaling: #{ex.inspect}"
|
18
18
|
end
|
@@ -20,10 +20,10 @@ module OurEelHacks
|
|
20
20
|
@app.call(env)
|
21
21
|
end
|
22
22
|
|
23
|
-
def
|
24
|
-
|
25
|
-
|
26
|
-
|
23
|
+
def metrics_from(env)
|
24
|
+
Hash[ @env_fields.map do |field|
|
25
|
+
[field, (Integer(env[field]) rescue 0)]
|
26
|
+
end ]
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
@@ -10,7 +10,7 @@ module OurEelHacks
|
|
10
10
|
|
11
11
|
def call(worker_class, item, queue)
|
12
12
|
begin
|
13
|
-
autoscale(get_queue_length(queue)
|
13
|
+
autoscale(get_queue_length(queue))
|
14
14
|
rescue => ex
|
15
15
|
puts "Problem in autoscaling: #{ex.inspect}"
|
16
16
|
end
|
@@ -18,9 +18,9 @@ module OurEelHacks
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def get_queue_length(queue)
|
21
|
-
::Sidekiq.redis do |conn|
|
21
|
+
{"queue_length" => ::Sidekiq.redis do |conn|
|
22
22
|
conn.llen("queue:#{queue}") || 0
|
23
|
-
end
|
23
|
+
end }
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
data/spec/autoscaler.rb
CHANGED
@@ -25,23 +25,23 @@ describe OurEelHacks::Autoscaler do
|
|
25
25
|
end
|
26
26
|
|
27
27
|
let :ideal_value do
|
28
|
-
25
|
28
|
+
{ "metric" => 25 }
|
29
29
|
end
|
30
30
|
|
31
31
|
let :soft_high do
|
32
|
-
35
|
32
|
+
{ "metric" => 35 }
|
33
33
|
end
|
34
34
|
|
35
35
|
let :soft_low do
|
36
|
-
3
|
36
|
+
{ "metric" => 3 }
|
37
37
|
end
|
38
38
|
|
39
39
|
let :hard_high do
|
40
|
-
100
|
40
|
+
{ "metric" => 100 }
|
41
41
|
end
|
42
42
|
|
43
43
|
let :hard_low do
|
44
|
-
-10
|
44
|
+
{ "metric" => -10 }
|
45
45
|
end
|
46
46
|
|
47
47
|
let :dyno_count do
|
@@ -89,6 +89,8 @@ describe OurEelHacks::Autoscaler do
|
|
89
89
|
test.upper_limits.soft = 30
|
90
90
|
test.upper_limits.hard = 50
|
91
91
|
|
92
|
+
#JDL: useful for debugging spec fails
|
93
|
+
#Irritating in general use
|
92
94
|
#test.logger = logger
|
93
95
|
end
|
94
96
|
end
|
@@ -103,17 +105,26 @@ describe OurEelHacks::Autoscaler do
|
|
103
105
|
end
|
104
106
|
|
105
107
|
before :each do
|
108
|
+
OurEelHacks::HerokuClient.processing_budget = 3
|
106
109
|
heroku.stub!(:ps_scale)
|
107
110
|
time_adjust(0)
|
108
111
|
autoscaler.scale(ideal_value)
|
109
112
|
end
|
110
113
|
|
114
|
+
def no_requests
|
115
|
+
OurEelHacks::HerokuClient.processing_budget = 0
|
116
|
+
heroku.should_not_receive(:ps_scale)
|
117
|
+
end
|
118
|
+
|
111
119
|
describe "scaling frequency" do
|
112
120
|
|
113
121
|
it "should not scale too soon" do
|
114
122
|
time_adjust(expected_scale_frequency - 5)
|
115
123
|
|
116
|
-
|
124
|
+
no_requests
|
125
|
+
autoscaler.scale(hard_high)
|
126
|
+
autoscaler.scale(hard_high)
|
127
|
+
autoscaler.scale(hard_high)
|
117
128
|
autoscaler.scale(hard_high)
|
118
129
|
end
|
119
130
|
|
@@ -163,15 +174,19 @@ describe OurEelHacks::Autoscaler do
|
|
163
174
|
describe "if soft_duration hasn't elapsed" do
|
164
175
|
before :each do
|
165
176
|
time_adjust((expected_scale_frequency * 2) + soft_dur - 5)
|
166
|
-
|
177
|
+
no_requests
|
167
178
|
end
|
168
179
|
|
169
180
|
it "should not scale up" do
|
170
181
|
autoscaler.scale(soft_high)
|
182
|
+
autoscaler.scale(soft_high)
|
183
|
+
autoscaler.scale(soft_high)
|
171
184
|
end
|
172
185
|
|
173
186
|
it "should not scale down" do
|
174
187
|
autoscaler.scale(soft_low)
|
188
|
+
autoscaler.scale(soft_high)
|
189
|
+
autoscaler.scale(soft_high)
|
175
190
|
end
|
176
191
|
end
|
177
192
|
|
data/spec/rack.rb
CHANGED
@@ -12,6 +12,7 @@ describe OurEelHacks::Rack do
|
|
12
12
|
end
|
13
13
|
|
14
14
|
before :each do
|
15
|
+
OurEelHacks::HerokuClient.processing_budget = 3
|
15
16
|
OurEelHacks::Autoscaler.configure(:test) do |test|
|
16
17
|
test.app_name = app_name
|
17
18
|
test.heroku_api_key = api_key
|
@@ -35,7 +36,7 @@ describe OurEelHacks::Rack do
|
|
35
36
|
|
36
37
|
|
37
38
|
it "should pass the metric to the autoscaler" do
|
38
|
-
OurEelHacks::Autoscaler.instance_for(:test).should_receive(:scale).with(100)
|
39
|
+
OurEelHacks::Autoscaler.instance_for(:test).should_receive(:scale).with({env_field => 100})
|
39
40
|
middleware.call({env_field => "100"})
|
40
41
|
end
|
41
42
|
end
|
data/spec_help/spec_helper.rb
CHANGED
@@ -12,6 +12,23 @@ RSpec.configure do |config|
|
|
12
12
|
config.extend VCR::RSpec::Macros
|
13
13
|
end
|
14
14
|
|
15
|
+
require 'our-eel-hacks/heroku-client'
|
16
|
+
class OurEelHacks::HerokuClient
|
17
|
+
alias real_process process
|
18
|
+
|
19
|
+
class << self
|
20
|
+
attr_accessor :processing_budget
|
21
|
+
end
|
22
|
+
|
23
|
+
def process(*args, &block)
|
24
|
+
#puts caller.grep %r{#{File::expand_path("../..",__FILE__)}}
|
25
|
+
if (self.class.processing_budget -= 1) < 0
|
26
|
+
raise "Exhausted processing budget"
|
27
|
+
end
|
28
|
+
real_process(*args, &block)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
15
32
|
$" << "eventmachine"
|
16
33
|
|
17
34
|
module EventMachine
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: our-eel-hacks
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.16
|
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-26 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: corundum
|
16
|
-
requirement: &
|
16
|
+
requirement: &71944990 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 0.0.1
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *71944990
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: heroku
|
27
|
-
requirement: &
|
27
|
+
requirement: &71940420 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -36,7 +36,7 @@ dependencies:
|
|
36
36
|
- 0
|
37
37
|
type: :runtime
|
38
38
|
prerelease: false
|
39
|
-
version_requirements: *
|
39
|
+
version_requirements: *71940420
|
40
40
|
description: ! " Middleware for Rack and Sidekiq to scale heroku.\n\n A heroku process
|
41
41
|
knows everything it needs in order to scale itself. A little configuration, and
|
42
42
|
you're set.\n"
|
@@ -68,7 +68,7 @@ rdoc_options:
|
|
68
68
|
- --main
|
69
69
|
- doc/README
|
70
70
|
- --title
|
71
|
-
- our-eel-hacks-0.0.
|
71
|
+
- our-eel-hacks-0.0.16 RDoc
|
72
72
|
require_paths:
|
73
73
|
- lib/
|
74
74
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -79,7 +79,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
79
79
|
version: '0'
|
80
80
|
segments:
|
81
81
|
- 0
|
82
|
-
hash:
|
82
|
+
hash: -980070001
|
83
83
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
84
84
|
none: false
|
85
85
|
requirements:
|