autoscaler 0.5.0 → 0.6.0
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/CHANGELOG.md +5 -0
- data/README.md +5 -0
- data/examples/simple.rb +1 -0
- data/lib/autoscaler/binary_scaling_strategy.rb +1 -1
- data/lib/autoscaler/heroku_scaler.rb +34 -2
- data/lib/autoscaler/sidekiq/client.rb +3 -1
- data/lib/autoscaler/version.rb +1 -1
- data/spec/autoscaler/heroku_scaler_spec.rb +23 -0
- metadata +2 -2
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 0.6.0
|
4
|
+
|
5
|
+
- Excon errors from the Heroku API are caught be default. See `HerokuScaler#exception_handler` to override behavior
|
6
|
+
- Client side scaling occurs after enquing the job, previously it was before.
|
7
|
+
|
3
8
|
## 0.5.0
|
4
9
|
|
5
10
|
- Experimental: `Client#set_initial_workers` to start workers on main process startup; typically:
|
data/README.md
CHANGED
@@ -41,11 +41,16 @@ Install the middleware in your `Sidekiq.configure_` blocks
|
|
41
41
|
- The scale-down monitor is triggered on job completion (and server middleware is only run around jobs), so if the server nevers processes any jobs, it won't turn off.
|
42
42
|
- The retry and schedule lists are considered - if you schedule a long-running task, the process will not scale-down.
|
43
43
|
- If background jobs trigger jobs in other scaled processes, please note you'll need `config.client_middleware` in your `Sidekiq.configure_server` block in order to scale-up.
|
44
|
+
- Exceptions while calling the Heroku API are caught and printed by default. See `HerokuScaler#exception_handler` to override
|
44
45
|
|
45
46
|
## Experimental
|
46
47
|
|
47
48
|
You can pass a scaling strategy object instead of the timeout to the server middleware. The object (or lambda) should respond to `#call(system, idle_time)` and return the desired number of workers. See `lib/autoscaler/binary_scaling_strategy.rb` for an example.
|
48
49
|
|
50
|
+
`Client#set_initial_workers` to start workers on main process startup; typically:
|
51
|
+
|
52
|
+
Autoscaler::Sidekiq::Client.add_to_chain(chain, 'default' => heroku).set_initial_workers
|
53
|
+
|
49
54
|
## Tests
|
50
55
|
|
51
56
|
The project is setup to run RSpec with Guard. It expects a redis instance on a custom port, which is started by the Guardfile.
|
data/examples/simple.rb
CHANGED
@@ -2,7 +2,7 @@ module Autoscaler
|
|
2
2
|
# Strategies determine the target number of workers
|
3
3
|
# The default strategy has a single worker when there is anything, or shuts it down.
|
4
4
|
class BinaryScalingStrategy
|
5
|
-
#@
|
5
|
+
#@param [integer] active_workers number of workers when in the active state.
|
6
6
|
def initialize(active_workers = 1)
|
7
7
|
@active_workers = active_workers
|
8
8
|
end
|
@@ -26,7 +26,7 @@ module Autoscaler
|
|
26
26
|
if known?
|
27
27
|
@workers
|
28
28
|
else
|
29
|
-
know
|
29
|
+
know heroku_get_workers
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
@@ -35,11 +35,23 @@ module Autoscaler
|
|
35
35
|
def workers=(n)
|
36
36
|
if n != @workers || !known?
|
37
37
|
p "Scaling #{type} to #{n}"
|
38
|
-
|
38
|
+
heroku_set_workers(n)
|
39
39
|
know n
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
+
# Callable object which responds to exceptions during api calls
|
44
|
+
#
|
45
|
+
# @example
|
46
|
+
# heroku.exception_handler = lambda {|exception| MyApp.logger.error(exception)}
|
47
|
+
# heroku.exception_handler = lambda {|exception| raise}
|
48
|
+
# # default
|
49
|
+
# lambda {|exception|
|
50
|
+
# p exception
|
51
|
+
# puts exception.backtrace
|
52
|
+
# }
|
53
|
+
attr_writer :exception_handler
|
54
|
+
|
43
55
|
private
|
44
56
|
attr_reader :client
|
45
57
|
|
@@ -51,5 +63,25 @@ module Autoscaler
|
|
51
63
|
def known?
|
52
64
|
Time.now < @known
|
53
65
|
end
|
66
|
+
|
67
|
+
def heroku_get_workers
|
68
|
+
client.get_ps(app).body.count {|ps| ps['process'].match /#{type}\.\d?/ }
|
69
|
+
rescue Excon::Errors::Error => e
|
70
|
+
exception_handler.call(e)
|
71
|
+
@workers
|
72
|
+
end
|
73
|
+
|
74
|
+
def heroku_set_workers(n)
|
75
|
+
client.post_ps_scale(app, type, n)
|
76
|
+
rescue Excon::Errors::Error => e
|
77
|
+
exception_handler.call(e)
|
78
|
+
end
|
79
|
+
|
80
|
+
def exception_handler
|
81
|
+
@exception_handler ||= lambda {|exception|
|
82
|
+
p exception
|
83
|
+
puts exception.backtrace
|
84
|
+
}
|
85
|
+
end
|
54
86
|
end
|
55
87
|
end
|
@@ -14,12 +14,14 @@ module Autoscaler
|
|
14
14
|
|
15
15
|
# Sidekiq middleware api method
|
16
16
|
def call(worker_class, item, queue)
|
17
|
+
result = yield
|
18
|
+
|
17
19
|
scaler = @scalers[queue]
|
18
20
|
if scaler && scaler.workers < 1
|
19
21
|
scaler.workers = 1
|
20
22
|
end
|
21
23
|
|
22
|
-
|
24
|
+
result
|
23
25
|
end
|
24
26
|
|
25
27
|
# Check for interrupted or scheduled work on startup.
|
data/lib/autoscaler/version.rb
CHANGED
@@ -17,4 +17,27 @@ describe Autoscaler::HerokuScaler, :online => true do
|
|
17
17
|
|
18
18
|
its(:workers) {should == 1}
|
19
19
|
end
|
20
|
+
|
21
|
+
describe 'exception handling', :focus => true do
|
22
|
+
before do
|
23
|
+
def client.client
|
24
|
+
raise Excon::Errors::SocketError.new(Exception.new('oops'))
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "default handler" do
|
29
|
+
it {expect{client.workers}.to_not raise_error}
|
30
|
+
it {client.workers.should == 0}
|
31
|
+
it {expect{client.workers = 1}.to_not raise_error}
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "custom handler" do
|
35
|
+
before do
|
36
|
+
@caught = false
|
37
|
+
client.exception_handler = lambda {|exception| @caught = true}
|
38
|
+
end
|
39
|
+
|
40
|
+
it {client.workers; @caught.should be_true}
|
41
|
+
end
|
42
|
+
end
|
20
43
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: autoscaler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-
|
13
|
+
date: 2013-09-05 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: sidekiq
|