From 2b78510c84ef872d30e36da87b8bcd4a4b010856 Mon Sep 17 00:00:00 2001 From: "Alexander J. Murmann" Date: Thu, 10 Feb 2011 07:05:50 -0800 Subject: [PATCH] adding Config --- .../plugins/heroku_autoscaler/config.rb | 34 ++++++++ .../plugins/heroku_autoscaler/version.rb | 3 + .../plugins/resque_heroku_autoscaler.rb | 11 ++- resque-heroku-autoscaler.gemspec | 2 +- spec/config_spec.rb | 86 +++++++++++++++++++ spec/resque_heroku_autoscaler_spec.rb | 20 ++++- 6 files changed, 149 insertions(+), 7 deletions(-) create mode 100644 lib/resque/plugins/heroku_autoscaler/config.rb create mode 100644 lib/resque/plugins/heroku_autoscaler/version.rb create mode 100644 spec/config_spec.rb diff --git a/lib/resque/plugins/heroku_autoscaler/config.rb b/lib/resque/plugins/heroku_autoscaler/config.rb new file mode 100644 index 0000000..16e8f6f --- /dev/null +++ b/lib/resque/plugins/heroku_autoscaler/config.rb @@ -0,0 +1,34 @@ +module Resque + module Plugins + module HerokuAutoscaler + module Config + extend self + + @new_worker_count = Proc.new {|pending| pending >0 ? 1 : 0} + + attr_writer :heroku_user + def heroku_user + @heroku_user || ENV['HEROKU_USER'] + end + + attr_writer :heroku_pass + def heroku_pass + @heroku_pass || ENV['HEROKU_PASS'] + end + + attr_writer :heroku_app + def heroku_app + @heroku_app || ENV['HEROKU_APP'] + end + + def new_worker_count(pending=nil, *payload, &calculate_count) + if calculate_count + @new_worker_count = calculate_count + else + @new_worker_count.call(pending, *payload) + end + end + end + end + end +end \ No newline at end of file diff --git a/lib/resque/plugins/heroku_autoscaler/version.rb b/lib/resque/plugins/heroku_autoscaler/version.rb new file mode 100644 index 0000000..167e138 --- /dev/null +++ b/lib/resque/plugins/heroku_autoscaler/version.rb @@ -0,0 +1,3 @@ +module Resque::Plugins::HerokuAutoscaler + VERSION = "0.1.0" +end diff --git a/lib/resque/plugins/resque_heroku_autoscaler.rb b/lib/resque/plugins/resque_heroku_autoscaler.rb index e7fa36a..6a3f1eb 100644 --- a/lib/resque/plugins/resque_heroku_autoscaler.rb +++ b/lib/resque/plugins/resque_heroku_autoscaler.rb @@ -1,3 +1,5 @@ +require 'resque/plugins/heroku_autoscaler/config' + module Resque module Plugins module HerokuAutoscaler @@ -12,11 +14,16 @@ def after_perform_scale_workers_down(*args) end def set_workers(number_of_workers) - heroku_client.set_workers(ENV['HEROKU_APP'], number_of_workers) + heroku_client.set_workers(Resque::Plugins::HerokuAutoscaler::Config.heroku_app, number_of_workers) end def heroku_client - @@heroku_client || @@heroku_client = Heroku::Client.new(ENV['HEROKU_USER'], ENV['HEROKU_PASS']) + @@heroku_client || @@heroku_client = Heroku::Client.new(Resque::Plugins::HerokuAutoscaler::Config.heroku_user, + Resque::Plugins::HerokuAutoscaler::Config.heroku_pass) + end + + def self.config + yield Resque::Plugins::HerokuAutoscaler::Config end end end diff --git a/resque-heroku-autoscaler.gemspec b/resque-heroku-autoscaler.gemspec index a06c300..cf2eb26 100644 --- a/resque-heroku-autoscaler.gemspec +++ b/resque-heroku-autoscaler.gemspec @@ -4,7 +4,7 @@ require 'resque/version' Gem::Specification.new do |s| s.name = "resque-heroku-autoscaler" s.date = Time.now.strftime('%Y-%m-%d') - s.version = "0.1.0" + s.version = Resque::Plugins::HerokuAutoscaler::VERSION s.summary = "Resque plugin to autoscale your workers on Heroku" s.homepage = "https://github.com/ajmurmann/resque-heroku-autoscaler" s.authors = ["Alexander Murmann"] diff --git a/spec/config_spec.rb b/spec/config_spec.rb new file mode 100644 index 0000000..06a5dbf --- /dev/null +++ b/spec/config_spec.rb @@ -0,0 +1,86 @@ +require 'rspec' +require 'heroku' +require 'resque' +require 'resque/plugins/heroku_autoscaler/config' + +describe Resque::Plugins::HerokuAutoscaler::Config do + describe ".heroku_user" do + it "stores the given heroku user name" do + subject.heroku_user = "my_user@example.com" + subject.heroku_user.should == "my_user@example.com" + end + + it "defaults to HEROKU_USER environment variable" do + subject.heroku_user = nil + ENV["HEROKU_USER"] = "user@example.com" + subject.heroku_user.should == "user@example.com" + end + end + + describe ".heroku_pass" do + it "stores the given heroku password" do + subject.heroku_pass = "password" + subject.heroku_pass.should == "password" + end + + it "defaults to HEROKU_PASS environment variable" do + subject.heroku_pass = nil + ENV["HEROKU_PASS"] = "123" + subject.heroku_pass.should == "123" + end + end + + describe ".heroku_app" do + it "stores the given heroku application name" do + subject.heroku_app = "my-grand-app" + subject.heroku_app.should == "my-grand-app" + end + + it "defaults to HEROKU_APP environment variable" do + subject.heroku_app = nil + ENV["HEROKU_APP"] = "yaa" + subject.heroku_app.should == "yaa" + end + end + + describe ".new_worker_count" do + before do + @original_method = Resque::Plugins::HerokuAutoscaler::Config.instance_variable_get(:@new_worker_count) + end + + after do + Resque::Plugins::HerokuAutoscaler::Config.instance_variable_set(:@new_worker_count, @original_method) + end + + it "should store a block as a Proc" do + subject.new_worker_count do |pending| + pending/5 + end + + subject.new_worker_count(10).should == 2 + end + + it "should be able to take the Resque job's payload as arguments" do + subject.new_worker_count do |pending, queue| + if queue == "test_queue" + 10 + else + pending/5 + end + end + + job_payload = ["test_queue", "more", "payload"] + puts "job_payload: #{job_payload.inspect}" + subject.new_worker_count(10, *job_payload).should == 10 + end + + context "when the proc was not yet set" do + before do + subject.new_worker_count do |pending, queue| + end + it { subject.new_worker_count(0).should == 0 } + it { subject.new_worker_count(1).should == 1 } + end + end + end +end \ No newline at end of file diff --git a/spec/resque_heroku_autoscaler_spec.rb b/spec/resque_heroku_autoscaler_spec.rb index e4c6187..076459f 100644 --- a/spec/resque_heroku_autoscaler_spec.rb +++ b/spec/resque_heroku_autoscaler_spec.rb @@ -80,7 +80,9 @@ class AnotherJob describe ".set_workers" do it "should use the Heroku client to set the workers" do - ENV['HEROKU_APP'] = 'some app name' + subject.config do |c| + c.heroku_app = 'some app name' + end mock(TestJob).heroku_client { mock!.set_workers('some app name', 10) } TestJob.set_workers(10) end @@ -88,8 +90,10 @@ class AnotherJob describe ".heroku_client" do before do - ENV['HEROKU_USER'] = 'john doe' - ENV['HEROKU_PASS'] = 'password' + subject.config do |c| + c.heroku_user = 'john doe' + c.heroku_pass = 'password' + end end it "should return a heroku client" do @@ -116,4 +120,12 @@ class AnotherJob TestJob.heroku_client.should == AnotherJob.heroku_client end end -end \ No newline at end of file + + describe ".config" do + it "yields the configuration" do + subject.config do |c| + c.should == Resque::Plugins::HerokuAutoscaler::Config + end + end + end +end