heroku-qc-autoscale 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/.travis.yml ADDED
@@ -0,0 +1,17 @@
1
+ language: ruby
2
+
3
+ notifications:
4
+ email: false
5
+ webhooks:
6
+ on_success: always
7
+ on_failure: always
8
+
9
+ rvm:
10
+ - 1.9.2
11
+ - 1.9.3
12
+
13
+ script: bundle exec rake test
14
+
15
+ before_script:
16
+ - psql -c 'create database queue_classic_test;' -U postgres
17
+
data/README.md CHANGED
@@ -5,6 +5,9 @@ Add to a Rails 3.x project to auto scale QueueClassic workers on heroku.
5
5
 
6
6
  **WARNING: USE AT OWN RISK! THIS GEM IS CONSIDERED EXTREME ALPHA!**
7
7
 
8
+ [![Build Status](https://secure.travis-ci.org/zerobearing2/heroku-qc-autoscale.png)](http://travis-ci.org/zerobearing2/heroku-qc-autoscale)
9
+
10
+
8
11
  Usage
9
12
  -----
10
13
 
@@ -19,7 +22,7 @@ Add to Gemfile
19
22
 
20
23
  Create config/initializers/qc_autoscale.rb
21
24
 
22
- Heroku::QC::Autoscale.config do |c|
25
+ Autoscale.config do |c|
23
26
  c.api_key = ENV['HEROKU_API_KEY']
24
27
  c.app = ENV['HEROKU_APP']
25
28
  c.scale = [1, 15, 30, 40, 50]
data/Rakefile CHANGED
@@ -1,8 +1,11 @@
1
1
  require "bundler/gem_tasks"
2
2
  require 'rake/testtask'
3
3
 
4
+ task :default => [:test]
5
+
4
6
  Rake::TestTask.new do |t|
5
7
  t.libs.push "lib"
6
8
  t.test_files = FileList[File.expand_path('../test/**/*_test.rb', __FILE__)]
7
9
  t.verbose = true
8
10
  end
11
+
@@ -25,5 +25,6 @@ Gem::Specification.new do |s|
25
25
  s.add_runtime_dependency "queue_classic", "~> 2.0.1"
26
26
 
27
27
  s.add_development_dependency "minitest", "~> 3.3.0"
28
+ s.add_development_dependency 'rake'
28
29
  s.add_development_dependency "pry"
29
30
  end
@@ -0,0 +1,63 @@
1
+ module Autoscale
2
+ class Heroku
3
+
4
+ class << self
5
+
6
+ def workers
7
+ client.get_app(app).body.fetch("workers", 0).to_i
8
+ end
9
+
10
+ def workers=(qty)
11
+ client.put_workers(app, qty)
12
+ end
13
+
14
+ def job_count
15
+ QC::Queries.count.to_i
16
+ end
17
+
18
+ # scale workers based on scale
19
+ def up
20
+ unless calculate_required_workers <= workers
21
+ QC.log(action: :scale, workers: calculate_required_workers)
22
+ self.workers = calculate_required_workers
23
+ end
24
+ end
25
+
26
+ # shutdown if no jobs exist
27
+ def down
28
+ if job_count < 1
29
+ QC.log(action: :scale, workers: 0)
30
+ self.workers = 0
31
+ end
32
+ end
33
+
34
+ def calculate_required_workers
35
+ scale.rindex{|x| x <= job_count} + 1
36
+ end
37
+
38
+ def params
39
+ {
40
+ api_key: Autoscale.api_key || ENV['HEROKU_API_KEY'],
41
+ mock: Autoscale.mock || false
42
+ }
43
+ end
44
+
45
+ # the app to scale
46
+ def app
47
+ Autoscale.app
48
+ end
49
+
50
+ # the scale
51
+ def scale
52
+ Autoscale.scale || [1, 15, 30, 40, 50]
53
+ end
54
+
55
+ # heroku api client
56
+ def client
57
+ @@client ||= ::Heroku::API.new( params )
58
+ end
59
+ end
60
+
61
+ end
62
+
63
+ end
@@ -0,0 +1,42 @@
1
+ module Autoscale
2
+ module QueueClassic
3
+
4
+ class ScaleObserver
5
+ def after_enqueue(caller)
6
+ Autoscale::Heroku.up
7
+ end
8
+
9
+ def after_delete(caller)
10
+ Autoscale::Heroku.down
11
+ end
12
+ end
13
+
14
+ module QueueCallbacks
15
+ extend ActiveSupport::Concern
16
+
17
+ included do
18
+ include ActiveSupport::Callbacks
19
+ define_callbacks :enqueue, :delete, :scope => [:kind, :name]
20
+ set_callback :enqueue, :after, ScaleObserver.new
21
+ set_callback :delete, :after, ScaleObserver.new
22
+
23
+ alias_method_chain :enqueue, :callbacks
24
+ alias_method_chain :delete, :callbacks
25
+ end
26
+
27
+ def enqueue_with_callbacks(method, *args)
28
+ run_callbacks :enqueue do
29
+ enqueue_without_callbacks(method, *args)
30
+ end
31
+ end
32
+
33
+ def delete_with_callbacks(id)
34
+ run_callbacks :delete do
35
+ delete_without_callbacks(id)
36
+ end
37
+ end
38
+ end
39
+
40
+ end
41
+ end
42
+
@@ -4,32 +4,21 @@ require 'active_support/core_ext/module'
4
4
  require 'queue_classic'
5
5
  require 'heroku-api'
6
6
 
7
+ require "autoscale/heroku"
8
+ require "autoscale/queue_classic/callbacks"
7
9
  require "heroku-qc-autoscale/version"
8
10
 
9
- require "qc/callbacks"
10
- require "qc/auto_scale"
11
- require "heroku/scaler"
11
+ module Autoscale
12
+ mattr_accessor :api_key, :app, :mock, :scale, :active
12
13
 
13
- module Heroku
14
- module QC
15
- module Autoscale
16
- mattr_accessor :api_key, :app, :mock, :scale, :active
17
-
18
- def self.config(&block)
19
- yield(self)
20
- activate if active == true
21
- end
22
-
23
- def self.activate
24
- ::QC::Queue.send(:include, ::QC::QueueCallbacks)
25
- end
14
+ # config and activate QC bindings
15
+ def self.config(&block)
16
+ yield(self)
17
+ activate if active == true
18
+ end
26
19
 
27
- def self.heroku_params
28
- {
29
- api_key: self.api_key || ENV['HEROKU_API_KEY'],
30
- mock: self.mock || false
31
- }
32
- end
33
- end
20
+ # activate QC queue callbacks
21
+ def self.activate
22
+ QC::Queue.send(:include, Autoscale::QueueClassic::QueueCallbacks)
34
23
  end
35
24
  end
@@ -1,7 +1,7 @@
1
1
  module Heroku
2
2
  module QC
3
3
  module Autoscale
4
- VERSION = "0.0.2"
4
+ VERSION = "0.0.3"
5
5
  end
6
6
  end
7
7
  end
@@ -1,11 +1,9 @@
1
1
  require_relative "../test_helper"
2
2
 
3
- describe Heroku::Scaler do
3
+ describe Autoscale::Heroku do
4
4
  include QCHelper
5
5
 
6
- QC.define_singleton_method :log do |*args| nil; end # silence QC logger
7
-
8
- subject { Heroku::Scaler }
6
+ subject { Autoscale::Heroku }
9
7
 
10
8
  it "job_count should be 0" do
11
9
  subject.job_count.must_equal(0)
@@ -1,4 +1,4 @@
1
- require_relative "../test_helper"
1
+ require_relative "../../test_helper"
2
2
 
3
3
  describe QC::Queue do
4
4
  subject { QC::Queue.new("default-test") }
@@ -1,23 +1,22 @@
1
1
  require_relative "./test_helper"
2
2
 
3
- describe Heroku::QC::Autoscale do
4
-
5
- before do
6
- Heroku::QC::Autoscale.config do |c|
7
- c.api_key = "123456"
8
- end
9
- end
10
-
11
- subject { Heroku::QC::Autoscale }
3
+ describe Autoscale do
4
+ subject { Autoscale }
12
5
 
13
6
  it "should have api_key" do
14
7
  subject.api_key.must_equal("123456")
15
8
  end
16
9
 
17
- it "should change api_key at runtime" do
18
- subject.api_key.must_equal("123456")
19
- subject.api_key = "654321"
20
- subject.api_key.must_equal("654321")
10
+ it "should have app name" do
11
+ subject.app.must_match /racehq-test/
12
+ end
13
+
14
+ it "should have scale" do
15
+ subject.scale.must_equal [1, 15, 30, 40, 50]
16
+ end
17
+
18
+ it "should have active" do
19
+ subject.active.must_equal true
21
20
  end
22
21
 
23
22
  end
@@ -2,12 +2,17 @@ module QCHelper
2
2
 
3
3
  def setup
4
4
  init_db
5
+ silence_logger
5
6
  end
6
7
 
7
8
  def teardown
8
9
  QC.delete_all
9
10
  end
10
11
 
12
+ def silence_logger
13
+ QC.define_singleton_method :log do |*args| nil; end # silence QC logger
14
+ end
15
+
11
16
  def init_db(table_name="queue_classic_jobs")
12
17
  QC::Conn.execute("SET client_min_messages TO 'warning'")
13
18
  QC::Setup.drop
data/test/test_helper.rb CHANGED
@@ -12,7 +12,7 @@ require 'time'
12
12
  require 'heroku-qc-autoscale'
13
13
  Dir[File.dirname(__FILE__) + "/support/**/*.rb"].each {|f| require f}
14
14
 
15
- Heroku::QC::Autoscale.config do |c|
15
+ Autoscale.config do |c|
16
16
  c.api_key = "123456"
17
17
  c.app = "racehq-test"
18
18
  c.mock = true
@@ -22,8 +22,8 @@ end
22
22
 
23
23
  # borrowed from heroku-api test helper
24
24
  def with_app(params={}, &block)
25
- params.merge!('name' => Heroku::QC::Autoscale.app) unless params.key?("name")
26
- heroku = Heroku::Scaler.client
25
+ params.merge!('name' => Autoscale.app) unless params.key?("name")
26
+ heroku = Autoscale::Heroku.client
27
27
 
28
28
  begin
29
29
  data = heroku.post_app(params).body
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: heroku-qc-autoscale
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -91,6 +91,22 @@ dependencies:
91
91
  - - ~>
92
92
  - !ruby/object:Gem::Version
93
93
  version: 3.3.0
94
+ - !ruby/object:Gem::Dependency
95
+ name: rake
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
94
110
  - !ruby/object:Gem::Dependency
95
111
  name: pry
96
112
  requirement: !ruby/object:Gem::Requirement
@@ -116,18 +132,18 @@ extra_rdoc_files: []
116
132
  files:
117
133
  - .gitignore
118
134
  - .rvmrc
135
+ - .travis.yml
119
136
  - Gemfile
120
137
  - README.md
121
138
  - Rakefile
122
139
  - heroku-qc-autoscale.gemspec
140
+ - lib/autoscale/heroku.rb
141
+ - lib/autoscale/queue_classic/callbacks.rb
123
142
  - lib/heroku-qc-autoscale.rb
124
143
  - lib/heroku-qc-autoscale/version.rb
125
- - lib/heroku/scaler.rb
126
- - lib/qc/auto_scale.rb
127
- - lib/qc/callbacks.rb
144
+ - test/autoscale/heroku_test.rb
145
+ - test/autoscale/queue_classic/callbacks_test.rb
128
146
  - test/autoscale_test.rb
129
- - test/heroku/scaler_test.rb
130
- - test/qc/queue_test.rb
131
147
  - test/support/qc_helper.rb
132
148
  - test/test_helper.rb
133
149
  homepage: ''
@@ -144,7 +160,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
144
160
  version: '0'
145
161
  segments:
146
162
  - 0
147
- hash: 4344916143927784136
163
+ hash: 3927445807195802384
148
164
  required_rubygems_version: !ruby/object:Gem::Requirement
149
165
  none: false
150
166
  requirements:
@@ -153,7 +169,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
153
169
  version: '0'
154
170
  segments:
155
171
  - 0
156
- hash: 4344916143927784136
172
+ hash: 3927445807195802384
157
173
  requirements: []
158
174
  rubyforge_project: heroku-qc-autoscale
159
175
  rubygems_version: 1.8.21
@@ -162,8 +178,8 @@ specification_version: 3
162
178
  summary: Auto scale your QueueClassic workers on Heroku. Inspired by mirthlab's Resque
163
179
  auto scale gem.
164
180
  test_files:
181
+ - test/autoscale/heroku_test.rb
182
+ - test/autoscale/queue_classic/callbacks_test.rb
165
183
  - test/autoscale_test.rb
166
- - test/heroku/scaler_test.rb
167
- - test/qc/queue_test.rb
168
184
  - test/support/qc_helper.rb
169
185
  - test/test_helper.rb
data/lib/heroku/scaler.rb DELETED
@@ -1,49 +0,0 @@
1
- module Heroku
2
- class Scaler
3
-
4
- class << self
5
- def workers
6
- client.get_app(app).body.fetch("workers", 0).to_i
7
- end
8
-
9
- def workers=(qty)
10
- client.put_workers(app, qty)
11
- end
12
-
13
- def job_count
14
- ::QC::Queries.count.to_i
15
- end
16
-
17
- # scale workers based on scale
18
- def up
19
- self.workers = calculate_required_workers unless calculate_required_workers <= workers
20
- end
21
-
22
- # shutdown if no jobs exist
23
- def down
24
- self.workers = 0 if job_count < 1
25
- end
26
-
27
- def calculate_required_workers
28
- scale.rindex{|x| x <= job_count} + 1
29
- end
30
-
31
- # the app to scale
32
- def app
33
- ::Heroku::QC::Autoscale.app
34
- end
35
-
36
- # the scale
37
- def scale
38
- ::Heroku::QC::Autoscale.scale || [1, 15, 30, 40, 50]
39
- end
40
-
41
- # heroku api client
42
- def client
43
- @@client ||= ::Heroku::API.new( ::Heroku::QC::Autoscale.heroku_params )
44
- end
45
- end
46
-
47
- end
48
-
49
- end
data/lib/qc/auto_scale.rb DELETED
@@ -1,13 +0,0 @@
1
- module QC
2
- class AutoScale
3
-
4
- def after_enqueue(caller)
5
- Heroku::Scaler.up
6
- end
7
-
8
- def after_delete(caller)
9
- Heroku::Scaler.down
10
- end
11
-
12
- end
13
- end
data/lib/qc/callbacks.rb DELETED
@@ -1,28 +0,0 @@
1
- module QC
2
- module QueueCallbacks
3
- extend ActiveSupport::Concern
4
-
5
- included do
6
- include ActiveSupport::Callbacks
7
- define_callbacks :enqueue, :delete, :scope => [:kind, :name]
8
- set_callback :enqueue, :after, QC::AutoScale.new
9
- set_callback :delete, :after, QC::AutoScale.new
10
-
11
- alias_method_chain :enqueue, :callbacks
12
- alias_method_chain :delete, :callbacks
13
- end
14
-
15
- def enqueue_with_callbacks(method, *args)
16
- run_callbacks :enqueue do
17
- enqueue_without_callbacks(method, *args)
18
- end
19
- end
20
-
21
- def delete_with_callbacks(id)
22
- run_callbacks :delete do
23
- delete_without_callbacks(id)
24
- end
25
- end
26
- end
27
- end
28
-