middle_management 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
data/.rvmrc ADDED
@@ -0,0 +1,3 @@
1
+ export RUBYOPT="rubygems"
2
+ export RUBYLIB="."
3
+ rvm 1.8.7@middle_management
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in middle_management.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,110 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ middle_management (0.0.1)
5
+ activesupport (~> 3.0)
6
+ delayed_job (>= 2.1.2)
7
+ heroku (>= 1.17.5)
8
+
9
+ GEM
10
+ remote: http://rubygems.org/
11
+ specs:
12
+ abstract (1.0.0)
13
+ actionmailer (3.0.3)
14
+ actionpack (= 3.0.3)
15
+ mail (~> 2.2.9)
16
+ actionpack (3.0.3)
17
+ activemodel (= 3.0.3)
18
+ activesupport (= 3.0.3)
19
+ builder (~> 2.1.2)
20
+ erubis (~> 2.6.6)
21
+ i18n (~> 0.4)
22
+ rack (~> 1.2.1)
23
+ rack-mount (~> 0.6.13)
24
+ rack-test (~> 0.5.6)
25
+ tzinfo (~> 0.3.23)
26
+ activemodel (3.0.3)
27
+ activesupport (= 3.0.3)
28
+ builder (~> 2.1.2)
29
+ i18n (~> 0.4)
30
+ activerecord (3.0.3)
31
+ activemodel (= 3.0.3)
32
+ activesupport (= 3.0.3)
33
+ arel (~> 2.0.2)
34
+ tzinfo (~> 0.3.23)
35
+ activeresource (3.0.3)
36
+ activemodel (= 3.0.3)
37
+ activesupport (= 3.0.3)
38
+ activesupport (3.0.3)
39
+ arel (2.0.7)
40
+ builder (2.1.2)
41
+ configuration (1.2.0)
42
+ daemons (1.1.0)
43
+ delayed_job (2.1.2)
44
+ activesupport (~> 3.0)
45
+ daemons
46
+ diff-lcs (1.1.2)
47
+ erubis (2.6.6)
48
+ abstract (>= 1.0.0)
49
+ fakeweb (1.3.0)
50
+ heroku (1.17.5)
51
+ json (~> 1.4.6)
52
+ launchy (~> 0.3.2)
53
+ rest-client (>= 1.4.0, < 1.7.0)
54
+ i18n (0.5.0)
55
+ json (1.4.6)
56
+ launchy (0.3.7)
57
+ configuration (>= 0.0.5)
58
+ rake (>= 0.8.1)
59
+ mail (2.2.14)
60
+ activesupport (>= 2.3.6)
61
+ i18n (>= 0.4.0)
62
+ mime-types (~> 1.16)
63
+ treetop (~> 1.4.8)
64
+ mime-types (1.16)
65
+ polyglot (0.3.1)
66
+ rack (1.2.1)
67
+ rack-mount (0.6.13)
68
+ rack (>= 1.0.0)
69
+ rack-test (0.5.7)
70
+ rack (>= 1.0)
71
+ rails (3.0.3)
72
+ actionmailer (= 3.0.3)
73
+ actionpack (= 3.0.3)
74
+ activerecord (= 3.0.3)
75
+ activeresource (= 3.0.3)
76
+ activesupport (= 3.0.3)
77
+ bundler (~> 1.0)
78
+ railties (= 3.0.3)
79
+ railties (3.0.3)
80
+ actionpack (= 3.0.3)
81
+ activesupport (= 3.0.3)
82
+ rake (>= 0.8.7)
83
+ thor (~> 0.14.4)
84
+ rake (0.8.7)
85
+ rest-client (1.6.1)
86
+ mime-types (>= 1.16)
87
+ rspec (2.4.0)
88
+ rspec-core (~> 2.4.0)
89
+ rspec-expectations (~> 2.4.0)
90
+ rspec-mocks (~> 2.4.0)
91
+ rspec-core (2.4.0)
92
+ rspec-expectations (2.4.0)
93
+ diff-lcs (~> 1.1.2)
94
+ rspec-mocks (2.4.0)
95
+ thor (0.14.6)
96
+ treetop (1.4.9)
97
+ polyglot (>= 0.3.1)
98
+ tzinfo (0.3.24)
99
+
100
+ PLATFORMS
101
+ ruby
102
+
103
+ DEPENDENCIES
104
+ activesupport (~> 3.0)
105
+ delayed_job (>= 2.1.2)
106
+ fakeweb (>= 1.3.0)
107
+ heroku (>= 1.17.5)
108
+ middle_management!
109
+ rails (~> 3.0)
110
+ rspec (>= 2.4.0)
data/README ADDED
@@ -0,0 +1,62 @@
1
+ Middle Management manages your Delayed Job workers on Heroku. It "hires" and "fires" workers automatically so that you get all of your work done quickly for as little money as possible.
2
+
3
+ It requires delayed_job 2.1.2 or greater.
4
+
5
+ To get started:
6
+
7
+ 1) Add "middle_management" to your Gemfile and run "bundle install"
8
+
9
+ 2) Set the following REQUIRED environment variables using heroku config:add KEY=value:
10
+ MIDDLE_MANAGEMENT_HEROKU_USERNAME (your heroku username)
11
+ MIDDLE_MANAGEMENT_HEROKU_PASSWORD (your heroku password)
12
+ MIDDLE_MANAGEMENT_HEROKU_APP (the name of your heroku app)
13
+ MIDDLE_MANAGEMENT_MIN_WORKERS (the minimum number of workers to keep running; typically 0)
14
+ MIDDLE_MANAGEMENT_MAX_WORKERS (the maximum number of workers to allow to run)
15
+
16
+ 3) Deploy to heroku and voila - you've got auto-scaling workers!
17
+
18
+ You can also limit the rate at which workers will scale up by setting:
19
+ MIDDLE_MANAGEMENT_JOBS_PER_WORKER (default = 1)
20
+ This should be the number of jobs a single worker can do more quickly than it takes to bring up another heroku worker. For short tasks with high throughput (e.g. sending emails), you should bump this up (I set it at 10). For long tasks with low throughput (e.g. PDF generation or traversing a social graph), keep this low.
21
+
22
+ How it works:
23
+
24
+ Every time a job is created or destroyed, Middle Management checks to see how many jobs are outstanding and how many workers are reserved to work on them. If the number of workers needed differs from the number of current workers, Middle Management hires or fires the needed or excess workers.
25
+
26
+ workers_needed is calculated as: outstanding jobs / MIDDLE_MANAGEMENT_JOBS_PER_WORKER
27
+
28
+ Middle Management will ALWAYS honor the maximum number of workers, as set by the MIDDLE_MANAGEMENT_MAX_WORKERS variable, and the minimum number of workers, as set by the MIDDLE_MANAGEMENT_MIN_WORKERS variable. If you use Delayed Job to schedule future jobs, you should always keep at least one worker running so that it can be worked off at the appropriate time. If all of your jobs are runnable at the time they are created, it is safe to set MIDDLE_MANAGEMENT_MIN_WORKERS to zero.
29
+
30
+ Step-by-step chart, assumes:
31
+ MIDDLE_MANAGEMENT_MIN_WORKERS=0
32
+ MIDDLE_MANAGEMENT_MAX_WORKERS=10
33
+ MIDDLE_MANAGEMENT_JOBS_PER_WORKER=1
34
+
35
+ App Action Middle Management Action Total Workers Running
36
+ Boot Up 0
37
+ Rotate 3 images Start 3 workers 3
38
+ First image rotated Stop 1 worker 2
39
+ Second image rotated Stop 1 worker 1
40
+ Send 105 emails with send_later Start 8 workers 10
41
+ First 10 emails sent 10
42
+ Next 10 emails sent 10
43
+ Next 10 emails sent 10
44
+ Next 10 emails sent 10
45
+ Next 10 emails sent 10
46
+ Next 10 emails sent 10
47
+ Next 10 emails sent 10
48
+ Next 10 emails sent 10
49
+ Next 10 emails sent 10
50
+ Next 10 emails sent Stop 5 workers 5
51
+ Last 5 emails sent Stop 5 workers 0
52
+
53
+ Testing in your heroku environment:
54
+
55
+ Middle Management comes with a Slacker class, whose sole purpose is to create jobs that take some time to run. You can use this class to create jobs in your production environment and monitor how your workers scale accordingly.
56
+
57
+ To get started, go to a heroku console and run:
58
+ > 30.times {MiddleManagement::Slacker.delay.slack_for(10)}
59
+
60
+ This will create 30 jobs, each of which sleeps for 10 seconds. Middle Management will scale your workers as these jobs are created and run off. You can monitor the changes to your worker count by using "heroku workers" from your command line.
61
+
62
+ http://github.com/freerobby/heroku_mbo is an empty rails app that includes this gem. If you want to fiddle with this gem in isolation, I recommend cloning that repo, creating a heroku app from it, and playing with it on a console.
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,10 @@
1
+ module MiddleManagement
2
+ class Config
3
+ HEROKU_USERNAME = ENV['MIDDLE_MANAGEMENT_HEROKU_USERNAME']
4
+ HEROKU_PASSWORD = ENV['MIDDLE_MANAGEMENT_HEROKU_PASSWORD']
5
+ HEROKU_APP = ENV['MIDDLE_MANAGEMENT_HEROKU_APP']
6
+ MIN_WORKERS = ENV['MIDDLE_MANAGEMENT_MIN_WORKERS'].to_i
7
+ MAX_WORKERS = ENV['MIDDLE_MANAGEMENT_MAX_WORKERS'].to_i
8
+ JOBS_PER_WORKER = ENV['MIDDLE_MANAGEMENT_JOBS_PER_WORKER'].to_i == 0 ? 1 : ENV['MIDDLE_MANAGEMENT_JOBS_PER_WORKER'].to_i
9
+ end
10
+ end
@@ -0,0 +1,12 @@
1
+ require 'delayed_job'
2
+ require 'delayed/backend/active_record'
3
+
4
+ class Delayed::Job < ::ActiveRecord::Base
5
+ after_create :enforce
6
+ after_destroy :enforce
7
+
8
+ private
9
+ def self.enforce
10
+ MiddleManagement::Manager.enforce_number_of_current_jobs(Delayed::Job.where("run_at <= ? AND failed_at IS NULL AND locked_by IS NULL", Delayed::Backend::ActiveRecord::Job.db_time_now).count)
11
+ end
12
+ end
@@ -0,0 +1,37 @@
1
+ require 'heroku'
2
+
3
+ module MiddleManagement
4
+ class Manager
5
+ def self.enforce_number_of_current_jobs(num)
6
+ self.set_num_workers(self.calculate_needed_worker_count(num)) if self.num_jobs_changes_worker_count?(num)
7
+ end
8
+
9
+ private
10
+ cattr_accessor :current_worker_count
11
+
12
+ def self.calculate_needed_worker_count(num_jobs)
13
+ ideal_worker_count = num_jobs / MiddleManagement::Config::JOBS_PER_WORKER + 1
14
+ ideal_worker_count -= 1 if num_jobs % MiddleManagement::Config::JOBS_PER_WORKER == 0
15
+ [MiddleManagement::Config::MIN_WORKERS, [ideal_worker_count, MiddleManagement::Config::MAX_WORKERS].min].max
16
+ end
17
+
18
+ def self.num_jobs_changes_worker_count?(num_jobs)
19
+ return false if num_jobs.nil?
20
+ return false if self.calculate_needed_worker_count(num_jobs) == current_worker_count
21
+ return true if current_worker_count.nil?
22
+ # Next two lines are verified in calculate_needed_worker_count(), but let's be safe since we're dealing with real money...
23
+ return false if self.calculate_needed_worker_count(num_jobs) < MiddleManagement::Config::MIN_WORKERS
24
+ return false if self.calculate_needed_worker_count(num_jobs) > MiddleManagement::Config::MAX_WORKERS
25
+ true
26
+ end
27
+
28
+ def self.get_heroku_client
29
+ Heroku::Client.new(MiddleManagement::Config::HEROKU_USERNAME, MiddleManagement::Config::HEROKU_PASSWORD)
30
+ end
31
+
32
+ def self.set_num_workers(num_workers)
33
+ self.get_heroku_client.set_workers(MiddleManagement::Config::HEROKU_APP, num_workers)
34
+ current_worker_count = num_workers
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,7 @@
1
+ module MiddleManagement
2
+ class Slacker
3
+ def self.slack_for(time_value_in_seconds)
4
+ sleep(time_value_in_seconds)
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ module MiddleManagement
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,4 @@
1
+ require 'middle_management/config'
2
+ require 'middle_management/job_modifications'
3
+ require 'middle_management/manager'
4
+ require 'middle_management/slacker'
@@ -0,0 +1,29 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "middle_management/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "middle_management"
7
+ s.version = MiddleManagement::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Robby Grossman"]
10
+ s.email = ["robby@freerobby.com"]
11
+ s.homepage = "http://github.com/freerobby/middle_management"
12
+ s.summary = %q{Delayed Job worker management for Heroku.}
13
+ s.description = %q{Middle Management hires and fires your delayed_job workers automatically so that you get all of your work done quickly for as little money as possible.}
14
+
15
+ s.add_runtime_dependency "activesupport", "~> 3.0"
16
+ s.add_runtime_dependency "delayed_job", ">= 2.1.2"
17
+ s.add_runtime_dependency "heroku", ">= 1.17.5"
18
+
19
+ s.add_development_dependency "fakeweb", ">= 1.3.0"
20
+ s.add_development_dependency "rails", "~> 3.0"
21
+ s.add_development_dependency "rspec", ">= 2.4.0"
22
+
23
+ s.rubyforge_project = "middle_management"
24
+
25
+ s.files = `git ls-files`.split("\n")
26
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
27
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
28
+ s.require_paths = ["lib"]
29
+ end
@@ -0,0 +1,18 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../spec_helper")
2
+
3
+ describe Delayed::Job do
4
+ before do
5
+ @client_mock = mock("Heroku Client")
6
+ MiddleManagement::Manager.should_receive(:get_heroku_client).any_number_of_times.and_return(@client_mock)
7
+ end
8
+
9
+ describe "#enforce" do
10
+ it "micromanages remaining jobs" do
11
+ MiddleManagement::Manager.should_receive(:enforce_number_of_current_jobs).with(3).exactly(:once)
12
+ Delayed::Job.should_receive(:count).exactly(:once).and_return(3)
13
+ Delayed::Backend::ActiveRecord::Job.should_receive(:db_time_now).and_return(Time.now)
14
+ Delayed::Job.should_receive(:where).any_number_of_times.and_return(Delayed::Job)
15
+ Delayed::Job.send(:enforce)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,171 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../spec_helper")
2
+
3
+ describe MiddleManagement::Manager do
4
+ describe "#enforce_number_of_current_jobs" do
5
+ before do
6
+ stub_config(:HEROKU_APP, "test_app")
7
+ stub_config(:MIN_WORKERS, 1)
8
+ stub_config(:MAX_WORKERS, 10)
9
+ @client_mock = mock("Heroku Client")
10
+ MiddleManagement::Manager.should_receive(:get_heroku_client).any_number_of_times.and_return(@client_mock)
11
+ end
12
+ describe "changes number of workers" do
13
+ it "makes api call" do
14
+ MiddleManagement::Manager.send(:current_worker_count=, 5)
15
+ @client_mock.should_receive(:set_workers).exactly(:once)
16
+ MiddleManagement::Manager.enforce_number_of_current_jobs(6)
17
+ end
18
+ end
19
+ describe "no change to number of workers" do
20
+ it "does not make api call" do
21
+ MiddleManagement::Manager.send(:current_worker_count=, 5)
22
+ @client_mock.should_not_receive(:set_workers)
23
+ MiddleManagement::Manager.enforce_number_of_current_jobs(5)
24
+ end
25
+ end
26
+ end
27
+
28
+ describe "private methods" do
29
+ describe "#calculate_needed_worker_count" do
30
+ describe "1 job per worker" do
31
+ before do
32
+ stub_config(:MIN_WORKERS, 1)
33
+ stub_config(:MAX_WORKERS, 10)
34
+ stub_config(:JOBS_PER_WORKER, 1)
35
+ end
36
+ it "returns min workers when fewer jobs than min workers" do
37
+ MiddleManagement::Manager.send(:calculate_needed_worker_count, 0).should == 1
38
+ end
39
+ it "returns max workers when more jobs than max workers" do
40
+ MiddleManagement::Manager.send(:calculate_needed_worker_count, 11).should == 10
41
+ end
42
+ it "returns number of jobs when job count in worker range" do
43
+ MiddleManagement::Manager.send(:calculate_needed_worker_count, 5).should == 5
44
+ end
45
+ end
46
+ describe "3 jobs per worker, MIN=0, MAX=10" do
47
+ before do
48
+ stub_config(:MIN_WORKERS, 0)
49
+ stub_config(:MAX_WORKERS, 10)
50
+ stub_config(:JOBS_PER_WORKER, 3)
51
+ end
52
+ it "returns 0 workers for 0 jobs" do
53
+ MiddleManagement::Manager.send(:calculate_needed_worker_count, 0).should == 0
54
+ end
55
+ end
56
+ describe "3 jobs per worker, MIN=1 MAX=10" do
57
+ before do
58
+ stub_config(:MIN_WORKERS, 1)
59
+ stub_config(:MAX_WORKERS, 10)
60
+ stub_config(:JOBS_PER_WORKER, 3)
61
+ end
62
+ it "returns 1 worker for 0 jobs" do
63
+ MiddleManagement::Manager.send(:calculate_needed_worker_count, 0).should == 1
64
+ end
65
+ it "returns 1 worker for 1 job" do
66
+ MiddleManagement::Manager.send(:calculate_needed_worker_count, 1).should == 1
67
+ end
68
+ it "returns 1 worker for 2 jobs" do
69
+ MiddleManagement::Manager.send(:calculate_needed_worker_count, 2).should == 1
70
+ end
71
+ it "returns 1 worker for 3 jobs" do
72
+ MiddleManagement::Manager.send(:calculate_needed_worker_count, 3).should == 1
73
+ end
74
+ it "returns 2 workers for 4 jobs" do
75
+ MiddleManagement::Manager.send(:calculate_needed_worker_count, 4).should == 2
76
+ end
77
+ it "returns 2 workers for 5 jobs" do
78
+ MiddleManagement::Manager.send(:calculate_needed_worker_count, 5).should == 2
79
+ end
80
+ it "returns 2 workers for 6 jobs" do
81
+ MiddleManagement::Manager.send(:calculate_needed_worker_count, 6).should == 2
82
+ end
83
+ it "returns 3 workers for 7 jobs" do
84
+ MiddleManagement::Manager.send(:calculate_needed_worker_count, 7).should == 3
85
+ end
86
+ it "returns 10 workers for 500 jobs" do
87
+ MiddleManagement::Manager.send(:calculate_needed_worker_count, 500).should == 10
88
+ end
89
+ end
90
+ end
91
+ describe "#num_jobs_changes_worker_count?" do
92
+ before do
93
+ stub_config(:MIN_WORKERS, 1)
94
+ stub_config(:MAX_WORKERS, 10)
95
+ stub_config(:JOBS_PER_WORKER, 1)
96
+ end
97
+ describe "running min workers" do
98
+ before do
99
+ MiddleManagement::Manager.send(:current_worker_count=, 1)
100
+ end
101
+ it "false to bring worker down" do
102
+ MiddleManagement::Manager.send(:num_jobs_changes_worker_count?, 0).should == false
103
+ end
104
+ it "true to bring worker up" do
105
+ MiddleManagement::Manager.send(:num_jobs_changes_worker_count?, 2).should == true
106
+ end
107
+ it "false to keep worker count" do
108
+ MiddleManagement::Manager.send(:num_jobs_changes_worker_count?, 1).should == false
109
+ end
110
+ end
111
+ describe "running max workers" do
112
+ before do
113
+ MiddleManagement::Manager.send(:current_worker_count=, 10)
114
+ end
115
+ it "true to bring worker down" do
116
+ MiddleManagement::Manager.send(:num_jobs_changes_worker_count?, 9).should == true
117
+ end
118
+ it "false to bring worker up" do
119
+ MiddleManagement::Manager.send(:num_jobs_changes_worker_count?, 11).should == false
120
+ end
121
+ it "false to keep worker count" do
122
+ MiddleManagement::Manager.send(:num_jobs_changes_worker_count?, 10).should == false
123
+ end
124
+ end
125
+ describe "num workers in middle of range" do
126
+ before do
127
+ MiddleManagement::Manager.send(:current_worker_count=, 5)
128
+ end
129
+ it "true to bring worker down" do
130
+ MiddleManagement::Manager.send(:num_jobs_changes_worker_count?, 4).should == true
131
+ end
132
+ it "true to bring worker up" do
133
+ MiddleManagement::Manager.send(:num_jobs_changes_worker_count?, 6).should == true
134
+ end
135
+ it "false to keep worker count" do
136
+ MiddleManagement::Manager.send(:num_jobs_changes_worker_count?, 5).should == false
137
+ end
138
+ end
139
+ describe "current_worker_count not set" do
140
+ before do
141
+ MiddleManagement::Manager.send(:current_worker_count=, nil)
142
+ end
143
+ it "true when setting to number" do
144
+ MiddleManagement::Manager.send(:num_jobs_changes_worker_count?, 1).should == true
145
+ end
146
+ it "false when setting to nil" do
147
+ MiddleManagement::Manager.send(:num_jobs_changes_worker_count?, nil).should == false
148
+ end
149
+ end
150
+ end
151
+
152
+ describe "#get_heroku_client" do
153
+ it "instantiates a heroku client using environment variables" do
154
+ stub_config(:HEROKU_USERNAME, "test_user")
155
+ stub_config(:HEROKU_PASSWORD, "test_pass")
156
+ Heroku::Client.should_receive(:new).with("test_user", "test_pass").exactly(:once)
157
+ MiddleManagement::Manager.send(:get_heroku_client)
158
+ end
159
+ end
160
+
161
+ describe "#set_num_workers" do
162
+ it "sets the specified number of workers" do
163
+ client_mock = mock("Heroku Client")
164
+ MiddleManagement::Manager.should_receive(:get_heroku_client).and_return(client_mock)
165
+ stub_config(:HEROKU_APP, "test_app")
166
+ client_mock.should_receive(:set_workers).with("test_app", 3).exactly(:once)
167
+ MiddleManagement::Manager.send(:set_num_workers, 3)
168
+ end
169
+ end
170
+ end
171
+ end
@@ -0,0 +1,4 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../spec_helper")
2
+
3
+ describe MiddleManagement do
4
+ end
@@ -0,0 +1,26 @@
1
+ require 'fakeweb'
2
+
3
+ require 'middle_management'
4
+
5
+ # Disable HTTP connections
6
+ RSpec.configure do |config|
7
+ config.before(:all) do
8
+ FakeWeb.allow_net_connect = false
9
+ end
10
+ end
11
+
12
+ # Backup and restore environment for each test
13
+ RSpec.configure do |config|
14
+ config.before(:each) do
15
+ @env_backup = Hash.new
16
+ ENV.keys.each {|key| @env_backup[key] = ENV[key]}
17
+ end
18
+ config.after(:each) do
19
+ @env_backup.keys.each {|key| ENV[key] = @env_backup[key]}
20
+ end
21
+ end
22
+
23
+ def stub_config(constant, value)
24
+ MiddleManagement::Config.send(:remove_const, constant)
25
+ MiddleManagement::Config.const_set(constant, value)
26
+ end
metadata ADDED
@@ -0,0 +1,180 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: middle_management
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Robby Grossman
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-01-16 00:00:00 -05:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: activesupport
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ hash: 7
30
+ segments:
31
+ - 3
32
+ - 0
33
+ version: "3.0"
34
+ type: :runtime
35
+ version_requirements: *id001
36
+ - !ruby/object:Gem::Dependency
37
+ name: delayed_job
38
+ prerelease: false
39
+ requirement: &id002 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ hash: 15
45
+ segments:
46
+ - 2
47
+ - 1
48
+ - 2
49
+ version: 2.1.2
50
+ type: :runtime
51
+ version_requirements: *id002
52
+ - !ruby/object:Gem::Dependency
53
+ name: heroku
54
+ prerelease: false
55
+ requirement: &id003 !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ hash: 89
61
+ segments:
62
+ - 1
63
+ - 17
64
+ - 5
65
+ version: 1.17.5
66
+ type: :runtime
67
+ version_requirements: *id003
68
+ - !ruby/object:Gem::Dependency
69
+ name: fakeweb
70
+ prerelease: false
71
+ requirement: &id004 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ hash: 27
77
+ segments:
78
+ - 1
79
+ - 3
80
+ - 0
81
+ version: 1.3.0
82
+ type: :development
83
+ version_requirements: *id004
84
+ - !ruby/object:Gem::Dependency
85
+ name: rails
86
+ prerelease: false
87
+ requirement: &id005 !ruby/object:Gem::Requirement
88
+ none: false
89
+ requirements:
90
+ - - ~>
91
+ - !ruby/object:Gem::Version
92
+ hash: 7
93
+ segments:
94
+ - 3
95
+ - 0
96
+ version: "3.0"
97
+ type: :development
98
+ version_requirements: *id005
99
+ - !ruby/object:Gem::Dependency
100
+ name: rspec
101
+ prerelease: false
102
+ requirement: &id006 !ruby/object:Gem::Requirement
103
+ none: false
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ hash: 31
108
+ segments:
109
+ - 2
110
+ - 4
111
+ - 0
112
+ version: 2.4.0
113
+ type: :development
114
+ version_requirements: *id006
115
+ description: Middle Management hires and fires your delayed_job workers automatically so that you get all of your work done quickly for as little money as possible.
116
+ email:
117
+ - robby@freerobby.com
118
+ executables: []
119
+
120
+ extensions: []
121
+
122
+ extra_rdoc_files: []
123
+
124
+ files:
125
+ - .gitignore
126
+ - .rvmrc
127
+ - Gemfile
128
+ - Gemfile.lock
129
+ - README
130
+ - Rakefile
131
+ - lib/middle_management.rb
132
+ - lib/middle_management/config.rb
133
+ - lib/middle_management/job_modifications.rb
134
+ - lib/middle_management/manager.rb
135
+ - lib/middle_management/slacker.rb
136
+ - lib/middle_management/version.rb
137
+ - middle_management.gemspec
138
+ - spec/lib/middle_management/job_modifications_spec.rb
139
+ - spec/lib/middle_management/manager_spec.rb
140
+ - spec/lib/middle_management_spec.rb
141
+ - spec/spec_helper.rb
142
+ has_rdoc: true
143
+ homepage: http://github.com/freerobby/middle_management
144
+ licenses: []
145
+
146
+ post_install_message:
147
+ rdoc_options: []
148
+
149
+ require_paths:
150
+ - lib
151
+ required_ruby_version: !ruby/object:Gem::Requirement
152
+ none: false
153
+ requirements:
154
+ - - ">="
155
+ - !ruby/object:Gem::Version
156
+ hash: 3
157
+ segments:
158
+ - 0
159
+ version: "0"
160
+ required_rubygems_version: !ruby/object:Gem::Requirement
161
+ none: false
162
+ requirements:
163
+ - - ">="
164
+ - !ruby/object:Gem::Version
165
+ hash: 3
166
+ segments:
167
+ - 0
168
+ version: "0"
169
+ requirements: []
170
+
171
+ rubyforge_project: middle_management
172
+ rubygems_version: 1.3.7
173
+ signing_key:
174
+ specification_version: 3
175
+ summary: Delayed Job worker management for Heroku.
176
+ test_files:
177
+ - spec/lib/middle_management/job_modifications_spec.rb
178
+ - spec/lib/middle_management/manager_spec.rb
179
+ - spec/lib/middle_management_spec.rb
180
+ - spec/spec_helper.rb