workless 1.0.2 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -7,9 +7,10 @@ It is designed to be used when you're using Heroku as a host and have the need t
7
7
 
8
8
  By adding the gem to your project and configuring our Heroku app with some config variables workless should do the rest.
9
9
 
10
- ## Update
10
+ ## Updates
11
11
 
12
- Version 1.0.0 has been released, this brings compatibility with delayed_job 3 and compatibility with Rails 2.3.x and up.
12
+ * Version 1.1.0 has been released, this adds support for scaling using multiple workers thanks to @jaimeiniesta and @davidakachaos.
13
+ * Version 1.0.0 has been released, this brings compatibility with delayed_job 3 and compatibility with Rails 2.3.x and up.
13
14
 
14
15
  ## Compatibility
15
16
 
@@ -48,17 +49,10 @@ gem "workless", "~> 1.0.1"
48
49
 
49
50
  If you don't specify delayed_job in your Gemfile workless will bring it in, most likly the latest version (3.0.1)
50
51
 
51
- Add your Heroku username / password as config vars to your Heroku instance, the same one you log in to Heroku with.
52
- [You may also use your API key as the password](https://github.com/heroku/heroku/issues/103).
52
+ Add your Heroku app name / [API key](https://devcenter.heroku.com/articles/authentication) as config vars to your Heroku instance.
53
53
 
54
54
  <pre>
55
- heroku config:add HEROKU_USER=yourusername HEROKU_PASSWORD=yourpassword
56
- </pre>
57
-
58
- And for cedar apps add the app name
59
-
60
- <pre>
61
- heroku config:add APP_NAME=yourherokuappname
55
+ heroku config:add HEROKU_API_KEY=yourapikey APP_NAME=yourherokuappname
62
56
  </pre>
63
57
 
64
58
  ## Failing Jobs
@@ -87,9 +81,21 @@ The local scaler uses @adamwiggins rush library http://github.com/adamwiggins/ru
87
81
 
88
82
  The heroku scaler works on the Aspen and Bamboo stacks while the heroku_cedar scaler only works on the new Cedar stack.
89
83
 
84
+ ## Scaling to multiple workers
85
+
86
+ As an experimental feature for the Cedar stack, Workless can scale to more than 1 worker based on the current work load. You just need to define these config variables on your app, setting the values you want:
87
+
88
+ <pre>
89
+ heroku config:add WORKLESS_MAX_WORKERS=10
90
+ heroku config:add WORKLESS_MIN_WORKERS=0
91
+ heroku config:add WORKLESS_WORKERS_RATIO=50
92
+ </pre>
93
+
94
+ In this example, it will scale up to a maximum of 10 workers, firing up 1 worker for every 50 jobs on the queue. The minimum will be 0 workers, but you could set it to a higher value if you want.
95
+
90
96
  ## Note on Patches/Pull Requests
91
97
 
92
- * Please fork the project, as you can see there are no tests and at present I don't know how to go about adding them so any advice would be welcome.
98
+ * Please fork the project.
93
99
  * Make your feature addition or bug fix.
94
100
  * Commit, do not mess with rakefile, version, or history.
95
101
  (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
data/lib/workless.rb CHANGED
@@ -1,4 +1,4 @@
1
- require "heroku"
1
+ require "heroku-api"
2
2
  require File.dirname(__FILE__) + "/workless/scalers/base"
3
3
  require File.dirname(__FILE__) + "/workless/scaler"
4
4
  require File.dirname(__FILE__) + "/workless/railtie" if defined?(Rails::Railtie)
@@ -19,14 +19,8 @@ module Delayed
19
19
 
20
20
  module ClassMethods
21
21
  def scaler
22
- @scaler ||= if ENV.include?("HEROKU_USER")
23
- client = ::Heroku::Client.new(ENV['HEROKU_USER'], ENV['HEROKU_PASSWORD'])
24
- case client.info(ENV["APP_NAME"])[:stack]
25
- when "cedar"
26
- Scaler::HerokuCedar
27
- else
28
- Scaler::Heroku
29
- end
22
+ @scaler ||= if ENV.include?("HEROKU_API_KEY")
23
+ Scaler::HerokuCedar
30
24
  else
31
25
  Scaler::Local
32
26
  end
@@ -13,7 +13,7 @@ module Delayed
13
13
  module HerokuClient
14
14
 
15
15
  def client
16
- @client ||= ::Heroku::Client.new(ENV['HEROKU_USER'], ENV['HEROKU_PASSWORD'])
16
+ @client ||= ::Heroku::API.new(:api_key => ENV['HEROKU_API_KEY'])
17
17
  end
18
18
 
19
19
  end
@@ -1,4 +1,4 @@
1
- require 'heroku'
1
+ require 'heroku-api'
2
2
 
3
3
  module Delayed
4
4
  module Workless
@@ -9,15 +9,15 @@ module Delayed
9
9
  extend Delayed::Workless::Scaler::HerokuClient
10
10
 
11
11
  def self.up
12
- client.set_workers(ENV['APP_NAME'], 1) if self.workers == 0
12
+ client.put_workers(ENV['APP_NAME'], 1) if self.workers == 0
13
13
  end
14
14
 
15
15
  def self.down
16
- client.set_workers(ENV['APP_NAME'], 0) unless self.workers == 0 or self.jobs.count > 0
16
+ client.put_workers(ENV['APP_NAME'], 0) unless self.workers == 0 or self.jobs.count > 0
17
17
  end
18
18
 
19
19
  def self.workers
20
- client.info(ENV['APP_NAME'])[:workers].to_i
20
+ client.get_ps(ENV['APP_NAME']).body.count { |p| p["process"] =~ /worker\.\d?/ }
21
21
  end
22
22
 
23
23
  end
@@ -1,27 +1,49 @@
1
- require 'heroku'
1
+ require 'heroku-api'
2
2
 
3
3
  module Delayed
4
4
  module Workless
5
5
  module Scaler
6
-
7
6
  class HerokuCedar < Base
8
-
9
7
  extend Delayed::Workless::Scaler::HerokuClient
10
8
 
11
9
  def self.up
12
- client.ps_scale(ENV['APP_NAME'], :type => 'worker', :qty => 1) if self.workers == 0
10
+ client.post_ps_scale(ENV['APP_NAME'], 'worker', self.workers_needed) if self.workers < self.workers_needed
13
11
  end
14
12
 
15
13
  def self.down
16
- client.ps_scale(ENV['APP_NAME'], :type => 'worker', :qty => 0) unless self.workers == 0 or self.jobs.count > 0
14
+ client.post_ps_scale(ENV['APP_NAME'], 'worker', self.min_workers) unless self.workers == self.min_workers or self.jobs.count > 0
17
15
  end
18
16
 
19
17
  def self.workers
20
- client.ps(ENV['APP_NAME']).count { |p| p["process"] =~ /worker\.\d?/ }
18
+ client.get_ps(ENV['APP_NAME']).body.count { |p| p["process"] =~ /worker\.\d?/ }
21
19
  end
22
20
 
23
- end
21
+ # Returns the number of workers needed based on the current number of pending jobs and the settings defined by:
22
+ #
23
+ # ENV['WORKLESS_WORKERS_RATIO']
24
+ # ENV['WORKLESS_MAX_WORKERS']
25
+ # ENV['WORKLESS_MIN_WORKERS']
26
+ #
27
+ def self.workers_needed
28
+ [[(self.jobs.count.to_f / self.workers_ratio).ceil, self.max_workers].min, self.min_workers].max
29
+ end
30
+
31
+ def self.workers_ratio
32
+ if ENV['WORKLESS_WORKERS_RATIO'].present? && (ENV['WORKLESS_WORKERS_RATIO'].to_i != 0)
33
+ ENV['WORKLESS_WORKERS_RATIO'].to_i
34
+ else
35
+ 100
36
+ end
37
+ end
38
+
39
+ def self.max_workers
40
+ ENV['WORKLESS_MAX_WORKERS'].present? ? ENV['WORKLESS_MAX_WORKERS'].to_i : 1
41
+ end
24
42
 
43
+ def self.min_workers
44
+ ENV['WORKLESS_MIN_WORKERS'].present? ? ENV['WORKLESS_MIN_WORKERS'].to_i : 0
45
+ end
46
+ end
25
47
  end
26
48
  end
27
- end
49
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: workless
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2011-06-30 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
16
- requirement: &70192881277980 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,15 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70192881277980
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
25
30
  - !ruby/object:Gem::Dependency
26
- name: heroku
27
- requirement: &70192881277400 !ruby/object:Gem::Requirement
31
+ name: heroku-api
32
+ requirement: !ruby/object:Gem::Requirement
28
33
  none: false
29
34
  requirements:
30
35
  - - ! '>='
@@ -32,10 +37,15 @@ dependencies:
32
37
  version: '0'
33
38
  type: :runtime
34
39
  prerelease: false
35
- version_requirements: *70192881277400
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
36
46
  - !ruby/object:Gem::Dependency
37
47
  name: rush
38
- requirement: &70192881276860 !ruby/object:Gem::Requirement
48
+ requirement: !ruby/object:Gem::Requirement
39
49
  none: false
40
50
  requirements:
41
51
  - - ! '>='
@@ -43,10 +53,15 @@ dependencies:
43
53
  version: '0'
44
54
  type: :runtime
45
55
  prerelease: false
46
- version_requirements: *70192881276860
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
47
62
  - !ruby/object:Gem::Dependency
48
63
  name: delayed_job
49
- requirement: &70192881276240 !ruby/object:Gem::Requirement
64
+ requirement: !ruby/object:Gem::Requirement
50
65
  none: false
51
66
  requirements:
52
67
  - - ! '>='
@@ -54,10 +69,15 @@ dependencies:
54
69
  version: 2.0.7
55
70
  type: :runtime
56
71
  prerelease: false
57
- version_requirements: *70192881276240
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: 2.0.7
58
78
  - !ruby/object:Gem::Dependency
59
79
  name: rspec
60
- requirement: &70192881275520 !ruby/object:Gem::Requirement
80
+ requirement: !ruby/object:Gem::Requirement
61
81
  none: false
62
82
  requirements:
63
83
  - - ! '>='
@@ -65,7 +85,12 @@ dependencies:
65
85
  version: '0'
66
86
  type: :development
67
87
  prerelease: false
68
- version_requirements: *70192881275520
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
69
94
  description: Extension to Delayed Job to enable workers to scale up when needed
70
95
  email: paul.crabtree@gmail.com
71
96
  executables: []
@@ -104,7 +129,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
104
129
  version: 1.3.6
105
130
  requirements: []
106
131
  rubyforge_project:
107
- rubygems_version: 1.8.6
132
+ rubygems_version: 1.8.24
108
133
  signing_key:
109
134
  specification_version: 3
110
135
  summary: Use delayed job workers only when theyre needed on Heroku