heroku-scalr 0.2.2 → 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +1 -1
- data/heroku-scalr.gemspec +1 -1
- data/lib/heroku/scalr/app.rb +3 -3
- data/lib/heroku/scalr/metric.rb +10 -2
- data/spec/heroku/scalr/app_spec.rb +1 -1
- data/spec/heroku/scalr/metric_spec.rb +20 -6
- metadata +1 -1
data/Gemfile.lock
CHANGED
data/heroku-scalr.gemspec
CHANGED
@@ -7,7 +7,7 @@ Gem::Specification.new do |s|
|
|
7
7
|
s.name = File.basename(__FILE__, '.gemspec')
|
8
8
|
s.summary = "Watch and scale your dynos!"
|
9
9
|
s.description = "Issues recurring 'pings' to your Heroku apps and scales dynos up or down depending on pre-defined rules"
|
10
|
-
s.version = "0.2.
|
10
|
+
s.version = "0.2.3"
|
11
11
|
|
12
12
|
s.authors = ["Black Square Media"]
|
13
13
|
s.email = "info@blacksquaremedia.com"
|
data/lib/heroku/scalr/app.rb
CHANGED
@@ -12,7 +12,7 @@ class Heroku::Scalr::App
|
|
12
12
|
min_frequency: 60
|
13
13
|
}.freeze
|
14
14
|
|
15
|
-
attr_reader :name, :
|
15
|
+
attr_reader :name, :url, :api, :interval, :min_dynos, :max_dynos,
|
16
16
|
:metric, :wait_low, :wait_high, :ping_low, :ping_high,
|
17
17
|
:min_frequency, :last_scaled_at
|
18
18
|
|
@@ -41,8 +41,8 @@ class Heroku::Scalr::App
|
|
41
41
|
fail("max_dynos must be at least 1") unless opts[:max_dynos] >= 1
|
42
42
|
fail("interval must be at least 10") unless opts[:interval] >= 10
|
43
43
|
|
44
|
-
@
|
45
|
-
@api
|
44
|
+
@url = opts[:url] || "http://#{@name}.herokuapp.com/robots.txt"
|
45
|
+
@api = Heroku::API.new api_key: opts[:api_key]
|
46
46
|
|
47
47
|
@interval = opts[:interval].to_i
|
48
48
|
@min_dynos = opts[:min_dynos].to_i
|
data/lib/heroku/scalr/metric.rb
CHANGED
@@ -26,6 +26,14 @@ module Heroku::Scalr::Metric
|
|
26
26
|
|
27
27
|
protected
|
28
28
|
|
29
|
+
def http_get
|
30
|
+
Excon.head(@app.url)
|
31
|
+
rescue Excon::Errors::Timeout
|
32
|
+
Excon::Response.new(status: 598)
|
33
|
+
rescue Excon::Errors::Error
|
34
|
+
Excon::Response.new(status: 444)
|
35
|
+
end
|
36
|
+
|
29
37
|
def compare(ms, low, high)
|
30
38
|
ms <= low ? -1 : (ms >= high ? 1 : 0)
|
31
39
|
end
|
@@ -43,7 +51,7 @@ module Heroku::Scalr::Metric
|
|
43
51
|
status = nil
|
44
52
|
|
45
53
|
real = Benchmark.realtime do
|
46
|
-
status =
|
54
|
+
status = http_get.status
|
47
55
|
end
|
48
56
|
|
49
57
|
unless status == 200
|
@@ -63,7 +71,7 @@ module Heroku::Scalr::Metric
|
|
63
71
|
|
64
72
|
# @see Heroku::Scalr::Metric::Abstract#by
|
65
73
|
def by
|
66
|
-
ms =
|
74
|
+
ms = http_get.headers["X-Heroku-Queue-Wait"]
|
67
75
|
unless ms
|
68
76
|
log :warn, "unable to determine queue wait time"
|
69
77
|
return 0
|
@@ -9,7 +9,7 @@ describe Heroku::Scalr::App do
|
|
9
9
|
end
|
10
10
|
|
11
11
|
its(:name) { should == 'name' }
|
12
|
-
its(:
|
12
|
+
its(:url) { should == 'http://name.herokuapp.com/robots.txt' }
|
13
13
|
its(:api) { should be_instance_of(Heroku::API) }
|
14
14
|
its(:metric) { should be_instance_of(Heroku::Scalr::Metric::Ping) }
|
15
15
|
|
@@ -15,17 +15,31 @@ end
|
|
15
15
|
|
16
16
|
describe Heroku::Scalr::Metric::Abstract do
|
17
17
|
|
18
|
+
let!(:http_request) { stub_request(:head, "http://name.herokuapp.com/robots.txt") }
|
18
19
|
let(:app) { Heroku::Scalr::App.new('name', api_key: 'key') }
|
19
20
|
subject { described_class.new(app) }
|
21
|
+
|
20
22
|
its(:by) { should == 0 }
|
21
23
|
|
24
|
+
it "should perform HTTP pings" do
|
25
|
+
res = subject.send(:http_get)
|
26
|
+
res.status.should == 200
|
27
|
+
http_request.should have_been_made
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should catch HTTP errors" do
|
31
|
+
Excon.stub!(:head).and_raise(Excon::Errors::Timeout)
|
32
|
+
res = subject.send(:http_get)
|
33
|
+
res.status.should == 598
|
34
|
+
end
|
35
|
+
|
22
36
|
end
|
23
37
|
|
24
38
|
describe Heroku::Scalr::Metric::Ping do
|
25
39
|
|
26
40
|
let(:app) { Heroku::Scalr::App.new('name', api_key: 'key') }
|
27
41
|
let(:ping_time) { 0.250 }
|
28
|
-
let!(:http_request) { stub_request(:
|
42
|
+
let!(:http_request) { stub_request(:head, "http://name.herokuapp.com/robots.txt") }
|
29
43
|
|
30
44
|
subject { described_class.new(app) }
|
31
45
|
before { Benchmark.stub(:realtime).and_yield.and_return(ping_time) }
|
@@ -58,7 +72,7 @@ describe Heroku::Scalr::Metric::Ping do
|
|
58
72
|
describe "failed requests" do
|
59
73
|
|
60
74
|
let! :http_request do
|
61
|
-
stub_request(:
|
75
|
+
stub_request(:head, "http://name.herokuapp.com/robots.txt").to_return(status: 404)
|
62
76
|
end
|
63
77
|
|
64
78
|
it 'should not scale' do
|
@@ -79,7 +93,7 @@ describe Heroku::Scalr::Metric::Wait do
|
|
79
93
|
describe "low queue wait time" do
|
80
94
|
|
81
95
|
let! :http_request do
|
82
|
-
stub_request(:
|
96
|
+
stub_request(:head, "http://name.herokuapp.com/robots.txt").to_return(body: "", headers: { "X-Heroku-Queue-Wait" => 3 })
|
83
97
|
end
|
84
98
|
|
85
99
|
it 'should scale down' do
|
@@ -92,7 +106,7 @@ describe Heroku::Scalr::Metric::Wait do
|
|
92
106
|
describe "high queue wait time" do
|
93
107
|
|
94
108
|
let! :http_request do
|
95
|
-
stub_request(:
|
109
|
+
stub_request(:head, "http://name.herokuapp.com/robots.txt").to_return(body: "", headers: { "X-Heroku-Queue-Wait" => 300 })
|
96
110
|
end
|
97
111
|
|
98
112
|
it 'should scale up' do
|
@@ -105,7 +119,7 @@ describe Heroku::Scalr::Metric::Wait do
|
|
105
119
|
describe "normal queue wait time" do
|
106
120
|
|
107
121
|
let! :http_request do
|
108
|
-
stub_request(:
|
122
|
+
stub_request(:head, "http://name.herokuapp.com/robots.txt").to_return(body: "", headers: { "X-Heroku-Queue-Wait" => 20 })
|
109
123
|
end
|
110
124
|
|
111
125
|
it 'should not scale' do
|
@@ -118,7 +132,7 @@ describe Heroku::Scalr::Metric::Wait do
|
|
118
132
|
describe "queue wait unretrievable" do
|
119
133
|
|
120
134
|
let! :http_request do
|
121
|
-
stub_request(:
|
135
|
+
stub_request(:head, "http://name.herokuapp.com/robots.txt")
|
122
136
|
end
|
123
137
|
|
124
138
|
it 'should not scale' do
|