resque-heroku-scaling-canary 0.1.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/Gemfile +12 -0
- data/LICENSE.txt +20 -0
- data/README.md +79 -0
- data/Rakefile +27 -0
- data/VERSION +1 -0
- data/lib/resque/plugins/resque_heroku_scaling_canary.rb +22 -0
- data/lib/resque/plugins/resque_heroku_scaling_canary/canary_job.rb +34 -0
- data/lib/resque/plugins/resque_heroku_scaling_canary/config.rb +43 -0
- data/resque-heroku-scaling-canary.gemspec +63 -0
- data/spec/config_spec.rb +15 -0
- data/spec/resque_heroku_scaling_canary_spec.rb +58 -0
- data/spec/spec_helper.rb +12 -0
- metadata +117 -0
data/Gemfile
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
|
3
|
+
gem 'resque', '~> 1.9'
|
4
|
+
gem 'heroku', '~> 1.11'
|
5
|
+
|
6
|
+
# Add dependencies to develop your gem here.
|
7
|
+
# Include everything needed to run rake, tests, features, etc.
|
8
|
+
group :development do
|
9
|
+
gem "rspec", "~> 2.7"
|
10
|
+
gem "rspec-mocks", "~> 2.7"
|
11
|
+
gem "jeweler", "~> 1.6.4"
|
12
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2012 Art.sy
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
resque-heroku-scaling-canary
|
2
|
+
============================
|
3
|
+
|
4
|
+
This gem defines a Resque plugin that allows you to automatically
|
5
|
+
scale up the number of workers running on Heroku and then automatically scale them down once
|
6
|
+
no work is left to do. To use, extend the module from your job:
|
7
|
+
|
8
|
+
class MyJob
|
9
|
+
extend Resque::Plugins::ScalingCanary
|
10
|
+
|
11
|
+
def self.minimum_workers_needed
|
12
|
+
10
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.perform
|
16
|
+
...
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
Defining `minimum_workers_needed` like we did above is optional, but if you don't define it, it
|
21
|
+
defaults to 1. ScalingCanary makes sure that when your job is enqueued there are at least this
|
22
|
+
many workers working to service it.
|
23
|
+
|
24
|
+
Next, define the environment variables HEROKU_USER, HEROKU_PASSWORD, and HEROKU_APP with your
|
25
|
+
heroku credentials and app name:
|
26
|
+
|
27
|
+
$ heroku config:add HEROKU_USER=aaron@art.sy
|
28
|
+
$ heroku config:add HEROKU_PASSWORD=5u93r53cr37
|
29
|
+
$ heroku config:add HEROKU_APP=awesome-app
|
30
|
+
|
31
|
+
When you enqueue your job, you'll see a new queue called "~scaling-canary" created with a single
|
32
|
+
job in it. This job is the canary - its queue name is lexicographically after any other queue
|
33
|
+
names you have, so it'll get processed last. When it runs, it looks around to see if any other
|
34
|
+
jobs are being worked on or are awaiting workers on any queues. If any are, it requeues itself,
|
35
|
+
but if everything's finished, it shuts down all workers.
|
36
|
+
|
37
|
+
There are a few other gems that allow you to automatically scale up the Heroku workers you
|
38
|
+
use in response to your Resque load and then kill those workers automatically when
|
39
|
+
the work is done: [resque-heroku-autoscaler](https://github.com/ajmurmann/resque-heroku-autoscaler)
|
40
|
+
and [hirefire](https://github.com/meskyanichi/hirefire) are two notable examples. This gem is
|
41
|
+
takes a dumber but more easily auditable approach than either of the above alternatives that's
|
42
|
+
better suited to systems running a largish set of batch jobs that might spawn other Resque jobs.
|
43
|
+
In particular, this gem is meant to work well with jobs using
|
44
|
+
[resque-multi-step](https://github.com/pezra/resque-multi-step), which enqueues finalization
|
45
|
+
jobs from within Resque tasks in a way that sometimes confuses other auto-scaling gems.
|
46
|
+
|
47
|
+
This plugin works with Resque version 1.9 and above.
|
48
|
+
|
49
|
+
Installation:
|
50
|
+
-------------
|
51
|
+
|
52
|
+
gem install resque_heroku_scaling_canary
|
53
|
+
|
54
|
+
Configuration:
|
55
|
+
--------------
|
56
|
+
|
57
|
+
You can configure the following parameters:
|
58
|
+
|
59
|
+
* `heroku_user`: defaults to the value of the environment variable HEROKU_USER
|
60
|
+
* `heroku_password`: defaults to the value of the environment variable HEROKU_PASSWORD
|
61
|
+
* `heroku_app`: defaults to the value of the environment variable HEROKU_APP
|
62
|
+
* `polling_interval`: the polling interval, in seconds, that the canary should wait
|
63
|
+
between checking the outstanding Resque jobs and working Resque workers. To be
|
64
|
+
safe, the canary checks these values twice, waiting for `polling_interval` seconds
|
65
|
+
in between, before shutting all workers down.
|
66
|
+
* `disable_scaling_if`: called with a block, will evaluate the block and disable
|
67
|
+
scaling entirely if it evaluates to `true`.
|
68
|
+
|
69
|
+
These values are easiest to configure in an initializer, for example, create the
|
70
|
+
file config/initializers/resque_heroku_scaling_canary.rb and put something like the
|
71
|
+
following in the file:
|
72
|
+
|
73
|
+
require 'resque_heroku_scaling_canary'
|
74
|
+
|
75
|
+
Resque::Plugins::ScalingCanary.config do |config|
|
76
|
+
config.heroku_app = "myapp"
|
77
|
+
config.polling_interval = 3
|
78
|
+
config.disable_scaling_if{ Rails.env == 'development' }
|
79
|
+
end
|
data/Rakefile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
require 'rake'
|
13
|
+
|
14
|
+
require 'jeweler'
|
15
|
+
Jeweler::Tasks.new do |gem|
|
16
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
17
|
+
gem.name = "resque-heroku-scaling-canary"
|
18
|
+
gem.homepage = "http://github.com/aaw/resque-heroku-scaling-canary"
|
19
|
+
gem.license = "MIT"
|
20
|
+
gem.summary = %Q{Auto-scale Heroku workers for Resque}
|
21
|
+
gem.description = %Q{Auto-scale Heroku workers for Resque}
|
22
|
+
gem.email = "aaron.windsor@gmail.com"
|
23
|
+
gem.authors = ["Aaron Windsor"]
|
24
|
+
# dependencies defined in Gemfile
|
25
|
+
end
|
26
|
+
Jeweler::RubygemsDotOrgTasks.new
|
27
|
+
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require "resque/plugins/resque_heroku_scaling_canary/config"
|
2
|
+
require "resque/plugins/resque_heroku_scaling_canary/canary_job"
|
3
|
+
|
4
|
+
module Resque
|
5
|
+
module Plugins
|
6
|
+
module ScalingCanary
|
7
|
+
|
8
|
+
def after_enqueue_ensure_heroku_workers(*args)
|
9
|
+
return if Config.scaling_disabled?
|
10
|
+
n = self.respond_to?(:minimum_workers_needed) ? self.minimum_workers_needed : 1
|
11
|
+
return if Config.heroku_client.info(Config.heroku_app)[:workers].to_i >= n
|
12
|
+
Config.heroku_client.set_workers(n)
|
13
|
+
Resque.enqueue(CanaryJob, Config.polling_interval) if CanaryJob.canary_jobs_pending == 0
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.config
|
17
|
+
yield Config
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require "resque/plugins/resque_heroku_scaling_canary/config"
|
2
|
+
|
3
|
+
module Resque
|
4
|
+
module Plugins
|
5
|
+
module ScalingCanary
|
6
|
+
class CanaryJob
|
7
|
+
|
8
|
+
@queue = "~scaling-canary"
|
9
|
+
|
10
|
+
def self.perform(timeout)
|
11
|
+
before = self.non_canary_jobs_pending
|
12
|
+
Kernel.sleep Config.polling_interval
|
13
|
+
after = self.non_canary_jobs_pending
|
14
|
+
if before == after and before == 0
|
15
|
+
Config.heroku_client.set_workers(0)
|
16
|
+
else
|
17
|
+
Resque.enqueue(self, timeout)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.canary_jobs_pending
|
22
|
+
Resque.size(@queue)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.non_canary_jobs_pending
|
26
|
+
waiting = Resque.queues.inject(0){ |accum, item| accum += Resque.size(item) unless item == @queue }
|
27
|
+
being_processed = Resque.workers.find_all{ |w| w.processing["queue"] and w.processing["queue"] != @queue }.count
|
28
|
+
waiting + being_processed
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Resque
|
2
|
+
module Plugins
|
3
|
+
module ScalingCanary
|
4
|
+
module Config
|
5
|
+
extend self
|
6
|
+
|
7
|
+
@disable_scaling_if = lambda { false }
|
8
|
+
def disable_scaling_if(&block)
|
9
|
+
@disable_scaling_if = block
|
10
|
+
end
|
11
|
+
|
12
|
+
def scaling_disabled?
|
13
|
+
@disable_scaling_if.call
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_writer :heroku_user
|
17
|
+
def heroku_user
|
18
|
+
@heroku_user ||= ENV['HEROKU_USER']
|
19
|
+
end
|
20
|
+
|
21
|
+
attr_writer :heroku_password
|
22
|
+
def heroku_password
|
23
|
+
@heroku_pass ||= ENV['HEROKU_PASS']
|
24
|
+
end
|
25
|
+
|
26
|
+
attr_writer :heroku_app
|
27
|
+
def heroku_app
|
28
|
+
@heroku_app ||= ENV['HEROKU_APP']
|
29
|
+
end
|
30
|
+
|
31
|
+
attr_writer :polling_interval
|
32
|
+
def polling_interval
|
33
|
+
@polling_interval ||= 5
|
34
|
+
end
|
35
|
+
|
36
|
+
def heroku_client
|
37
|
+
@@heroku_client ||= Heroku::Client.new(Config.heroku_user, Config.heroku_password)
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "resque-heroku-scaling-canary"
|
8
|
+
s.version = "0.1.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Aaron Windsor"]
|
12
|
+
s.date = "2012-01-30"
|
13
|
+
s.description = "Auto-scale Heroku workers for Resque"
|
14
|
+
s.email = "aaron.windsor@gmail.com"
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE.txt",
|
17
|
+
"README.md"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
"Gemfile",
|
21
|
+
"LICENSE.txt",
|
22
|
+
"README.md",
|
23
|
+
"Rakefile",
|
24
|
+
"VERSION",
|
25
|
+
"lib/resque/plugins/resque_heroku_scaling_canary.rb",
|
26
|
+
"lib/resque/plugins/resque_heroku_scaling_canary/canary_job.rb",
|
27
|
+
"lib/resque/plugins/resque_heroku_scaling_canary/config.rb",
|
28
|
+
"resque-heroku-scaling-canary.gemspec",
|
29
|
+
"spec/config_spec.rb",
|
30
|
+
"spec/resque_heroku_scaling_canary_spec.rb",
|
31
|
+
"spec/spec_helper.rb"
|
32
|
+
]
|
33
|
+
s.homepage = "http://github.com/aaw/resque-heroku-scaling-canary"
|
34
|
+
s.licenses = ["MIT"]
|
35
|
+
s.require_paths = ["lib"]
|
36
|
+
s.rubygems_version = "1.8.10"
|
37
|
+
s.summary = "Auto-scale Heroku workers for Resque"
|
38
|
+
|
39
|
+
if s.respond_to? :specification_version then
|
40
|
+
s.specification_version = 3
|
41
|
+
|
42
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
43
|
+
s.add_runtime_dependency(%q<resque>, ["~> 1.9"])
|
44
|
+
s.add_runtime_dependency(%q<heroku>, ["~> 1.11"])
|
45
|
+
s.add_development_dependency(%q<rspec>, ["~> 2.7"])
|
46
|
+
s.add_development_dependency(%q<rspec-mocks>, ["~> 2.7"])
|
47
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
|
48
|
+
else
|
49
|
+
s.add_dependency(%q<resque>, ["~> 1.9"])
|
50
|
+
s.add_dependency(%q<heroku>, ["~> 1.11"])
|
51
|
+
s.add_dependency(%q<rspec>, ["~> 2.7"])
|
52
|
+
s.add_dependency(%q<rspec-mocks>, ["~> 2.7"])
|
53
|
+
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
54
|
+
end
|
55
|
+
else
|
56
|
+
s.add_dependency(%q<resque>, ["~> 1.9"])
|
57
|
+
s.add_dependency(%q<heroku>, ["~> 1.11"])
|
58
|
+
s.add_dependency(%q<rspec>, ["~> 2.7"])
|
59
|
+
s.add_dependency(%q<rspec-mocks>, ["~> 2.7"])
|
60
|
+
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
data/spec/config_spec.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Resque::Plugins::ScalingCanary::Config do
|
4
|
+
describe "scaling_disabled?" do
|
5
|
+
it "returns false by default" do
|
6
|
+
subject.scaling_disabled?.should be_false
|
7
|
+
end
|
8
|
+
it "returns the results of a call to disable_scaling_if when an implementation is provided" do
|
9
|
+
subject.disable_scaling_if{ true }
|
10
|
+
subject.scaling_disabled?.should be_true
|
11
|
+
subject.disable_scaling_if{ false }
|
12
|
+
subject.scaling_disabled?.should be_false
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
class SmallBatchJob
|
4
|
+
extend Resque::Plugins::ScalingCanary
|
5
|
+
@queue = 'small-batch-job'
|
6
|
+
|
7
|
+
def self.perform; end
|
8
|
+
end
|
9
|
+
|
10
|
+
class LargeBatchJob
|
11
|
+
extend Resque::Plugins::ScalingCanary
|
12
|
+
@queue = 'large-batch-job'
|
13
|
+
|
14
|
+
def self.minimum_workers_needed
|
15
|
+
20
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.perform; end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe Resque::Plugins::ScalingCanary do
|
22
|
+
before(:each) do
|
23
|
+
@mock_heroku_client = Object.new
|
24
|
+
Resque::Plugins::ScalingCanary.config do |config|
|
25
|
+
config.heroku_user = "stub"
|
26
|
+
config.heroku_password = "stub"
|
27
|
+
config.heroku_app = "stub"
|
28
|
+
config.polling_interval = 0
|
29
|
+
config.stub(:heroku_client) { @mock_heroku_client }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should pass Resque's plugin lint test" do
|
34
|
+
lambda { Resque::Plugin.lint(Resque::Plugins::ScalingCanary) }.should_not raise_error
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "after_enqueue_ensure_heroku_workers" do
|
38
|
+
it "should scale workers up to 1 if no :minimum_workers_needed method is implemented" do
|
39
|
+
@mock_heroku_client.should_receive(:set_workers).with(1).once
|
40
|
+
@mock_heroku_client.should_receive(:set_workers).with(0).once
|
41
|
+
@mock_heroku_client.stub(:info) { {:workers => 0} }
|
42
|
+
Resque.enqueue SmallBatchJob
|
43
|
+
end
|
44
|
+
it "should scale workers up to the number specified by :minimum_workers_needed if an implementation is provided" do
|
45
|
+
@mock_heroku_client.should_receive(:set_workers).with(20).once
|
46
|
+
@mock_heroku_client.should_receive(:set_workers).with(0).once
|
47
|
+
@mock_heroku_client.stub(:info) { {:workers => 0} }
|
48
|
+
Resque.enqueue LargeBatchJob
|
49
|
+
end
|
50
|
+
it "should not scale workers at all if scaling is disabled" do
|
51
|
+
Resque::Plugins::ScalingCanary::Config.disable_scaling_if{ true }
|
52
|
+
@mock_heroku_client.stub(:set_workers){ raise "Not expecting call to :set_workers because scaling is disabled" }
|
53
|
+
@mock_heroku_client.stub(:info) { {:workers => 0} }
|
54
|
+
Resque.enqueue LargeBatchJob
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require 'heroku'
|
3
|
+
require 'resque'
|
4
|
+
require 'resque/plugins/resque_heroku_scaling_canary/config'
|
5
|
+
require 'resque/plugins/resque_heroku_scaling_canary'
|
6
|
+
|
7
|
+
RSpec.configure do |config|
|
8
|
+
config.mock_with :rspec
|
9
|
+
config.expect_with :rspec
|
10
|
+
end
|
11
|
+
|
12
|
+
Resque.inline = true
|
metadata
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: resque-heroku-scaling-canary
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Aaron Windsor
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-01-30 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: resque
|
16
|
+
requirement: &2164966460 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '1.9'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *2164966460
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: heroku
|
27
|
+
requirement: &2164965560 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ~>
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '1.11'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *2164965560
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rspec
|
38
|
+
requirement: &2164964420 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '2.7'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *2164964420
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rspec-mocks
|
49
|
+
requirement: &2164963280 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '2.7'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *2164963280
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: jeweler
|
60
|
+
requirement: &2164962200 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ~>
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: 1.6.4
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *2164962200
|
69
|
+
description: Auto-scale Heroku workers for Resque
|
70
|
+
email: aaron.windsor@gmail.com
|
71
|
+
executables: []
|
72
|
+
extensions: []
|
73
|
+
extra_rdoc_files:
|
74
|
+
- LICENSE.txt
|
75
|
+
- README.md
|
76
|
+
files:
|
77
|
+
- Gemfile
|
78
|
+
- LICENSE.txt
|
79
|
+
- README.md
|
80
|
+
- Rakefile
|
81
|
+
- VERSION
|
82
|
+
- lib/resque/plugins/resque_heroku_scaling_canary.rb
|
83
|
+
- lib/resque/plugins/resque_heroku_scaling_canary/canary_job.rb
|
84
|
+
- lib/resque/plugins/resque_heroku_scaling_canary/config.rb
|
85
|
+
- resque-heroku-scaling-canary.gemspec
|
86
|
+
- spec/config_spec.rb
|
87
|
+
- spec/resque_heroku_scaling_canary_spec.rb
|
88
|
+
- spec/spec_helper.rb
|
89
|
+
homepage: http://github.com/aaw/resque-heroku-scaling-canary
|
90
|
+
licenses:
|
91
|
+
- MIT
|
92
|
+
post_install_message:
|
93
|
+
rdoc_options: []
|
94
|
+
require_paths:
|
95
|
+
- lib
|
96
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
segments:
|
103
|
+
- 0
|
104
|
+
hash: 2123918992578808626
|
105
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
106
|
+
none: false
|
107
|
+
requirements:
|
108
|
+
- - ! '>='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
requirements: []
|
112
|
+
rubyforge_project:
|
113
|
+
rubygems_version: 1.8.10
|
114
|
+
signing_key:
|
115
|
+
specification_version: 3
|
116
|
+
summary: Auto-scale Heroku workers for Resque
|
117
|
+
test_files: []
|