governor_background 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.
Files changed (86) hide show
  1. data/.document +5 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +28 -0
  4. data/Gemfile.lock +163 -0
  5. data/LICENSE.txt +20 -0
  6. data/README.rdoc +91 -0
  7. data/Rakefile +50 -0
  8. data/VERSION +1 -0
  9. data/app/helpers/governor_background_helper.rb +11 -0
  10. data/governor_background.gemspec +206 -0
  11. data/lib/governor_background/controllers/methods.rb +18 -0
  12. data/lib/governor_background/delayed/job.rb +70 -0
  13. data/lib/governor_background/delayed/performer.rb +13 -0
  14. data/lib/governor_background/handler.rb +34 -0
  15. data/lib/governor_background/job_manager.rb +22 -0
  16. data/lib/governor_background/rails.rb +8 -0
  17. data/lib/governor_background/resque/job.rb +51 -0
  18. data/lib/governor_background/resque/performer.rb +12 -0
  19. data/lib/governor_background/resque/performer_with_state.rb +17 -0
  20. data/lib/governor_background.rb +22 -0
  21. data/spec/governor_background/delayed/job_spec.rb +47 -0
  22. data/spec/governor_background/handler_spec.rb +46 -0
  23. data/spec/governor_background/job_manager_spec.rb +44 -0
  24. data/spec/governor_background/resque/performer_spec.rb +17 -0
  25. data/spec/governor_background/resque/performer_with_state_spec.rb +18 -0
  26. data/spec/governor_background_spec.rb +7 -0
  27. data/spec/rails_app/.gitignore +4 -0
  28. data/spec/rails_app/Gemfile +43 -0
  29. data/spec/rails_app/Gemfile.lock +128 -0
  30. data/spec/rails_app/README +256 -0
  31. data/spec/rails_app/Rakefile +7 -0
  32. data/spec/rails_app/app/controllers/application_controller.rb +3 -0
  33. data/spec/rails_app/app/controllers/home_controller.rb +2 -0
  34. data/spec/rails_app/app/helpers/application_helper.rb +2 -0
  35. data/spec/rails_app/app/helpers/home_helper.rb +2 -0
  36. data/spec/rails_app/app/models/article.rb +5 -0
  37. data/spec/rails_app/app/models/user.rb +9 -0
  38. data/spec/rails_app/app/views/governor/articles/index.xml.builder +5 -0
  39. data/spec/rails_app/app/views/home/index.html.erb +0 -0
  40. data/spec/rails_app/app/views/layouts/application.html.erb +22 -0
  41. data/spec/rails_app/config/application.rb +42 -0
  42. data/spec/rails_app/config/boot.rb +14 -0
  43. data/spec/rails_app/config/database.yml +19 -0
  44. data/spec/rails_app/config/environment.rb +5 -0
  45. data/spec/rails_app/config/environments/development.rb +26 -0
  46. data/spec/rails_app/config/environments/production.rb +49 -0
  47. data/spec/rails_app/config/environments/test.rb +35 -0
  48. data/spec/rails_app/config/initializers/backtrace_silencers.rb +7 -0
  49. data/spec/rails_app/config/initializers/devise.rb +142 -0
  50. data/spec/rails_app/config/initializers/governor.rb +36 -0
  51. data/spec/rails_app/config/initializers/inflections.rb +10 -0
  52. data/spec/rails_app/config/initializers/mime_types.rb +5 -0
  53. data/spec/rails_app/config/initializers/resque.rb +5 -0
  54. data/spec/rails_app/config/initializers/secret_token.rb +7 -0
  55. data/spec/rails_app/config/initializers/session_store.rb +8 -0
  56. data/spec/rails_app/config/locales/devise.en.yml +39 -0
  57. data/spec/rails_app/config/locales/en.yml +5 -0
  58. data/spec/rails_app/config/redis.yml +15 -0
  59. data/spec/rails_app/config/routes.rb +64 -0
  60. data/spec/rails_app/config.ru +4 -0
  61. data/spec/rails_app/db/migrate/20110329032256_devise_create_users.rb +26 -0
  62. data/spec/rails_app/db/migrate/20110330020108_governor_create_articles.rb +15 -0
  63. data/spec/rails_app/db/migrate/20110421014910_create_delayed_jobs.rb +21 -0
  64. data/spec/rails_app/db/schema.rb +59 -0
  65. data/spec/rails_app/db/seeds.rb +7 -0
  66. data/spec/rails_app/lib/tasks/.gitkeep +0 -0
  67. data/spec/rails_app/lib/tasks/resque.rake +2 -0
  68. data/spec/rails_app/public/404.html +26 -0
  69. data/spec/rails_app/public/422.html +26 -0
  70. data/spec/rails_app/public/500.html +26 -0
  71. data/spec/rails_app/public/favicon.ico +0 -0
  72. data/spec/rails_app/public/images/rails.png +0 -0
  73. data/spec/rails_app/public/javascripts/application.js +2 -0
  74. data/spec/rails_app/public/javascripts/controls.js +965 -0
  75. data/spec/rails_app/public/javascripts/dragdrop.js +974 -0
  76. data/spec/rails_app/public/javascripts/effects.js +1123 -0
  77. data/spec/rails_app/public/javascripts/prototype.js +6001 -0
  78. data/spec/rails_app/public/javascripts/rails.js +191 -0
  79. data/spec/rails_app/public/robots.txt +5 -0
  80. data/spec/rails_app/public/stylesheets/.gitkeep +0 -0
  81. data/spec/rails_app/script/delayed_job +5 -0
  82. data/spec/rails_app/script/rails +6 -0
  83. data/spec/rails_app/spec/factories.rb +12 -0
  84. data/spec/rails_app/vendor/plugins/.gitkeep +0 -0
  85. data/spec/spec_helper.rb +36 -0
  86. metadata +417 -0
@@ -0,0 +1,13 @@
1
+ module GovernorBackground
2
+ module Delayed
3
+ class Performer < Struct.new(:article, :method_name)
4
+ def perform
5
+ article.send(method_name)
6
+ end
7
+
8
+ def error(job, exception)
9
+ # handle failure
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,34 @@
1
+ module GovernorBackground
2
+ class Handler
3
+ class << self
4
+ def run_in_background(object, method)
5
+ job = if delayed_job?
6
+ Delayed::Job.new(object, method, ::Delayed::Job.enqueue(Delayed::Performer.new(object, method)))
7
+ elsif resque?
8
+ resource_key, id = object.class.name.tableize.to_sym, object.id
9
+ if resque_with_status?
10
+ require File.expand_path('../resque/performer_with_state', __FILE__)
11
+ Resque::Job.new(object, method, Resque::PerformerWithState.create(:resource => resource_key, :id => id, :method_name => method))
12
+ else
13
+ ::Resque.enqueue(Resque::Performer, resource_key, id, method)
14
+ nil # not much use in holding on to state if we can't track it
15
+ end
16
+ end
17
+ JobManager.add(job) unless job.blank?
18
+ end
19
+
20
+ private
21
+ def delayed_job?
22
+ defined? ::Delayed::Job
23
+ end
24
+
25
+ def resque?
26
+ defined? ::Resque
27
+ end
28
+
29
+ def resque_with_status?
30
+ defined? ::Resque::Status
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,22 @@
1
+ module GovernorBackground
2
+ class JobManager
3
+ @@finished_statuses = %w(completed failed killed).freeze
4
+ cattr_reader :jobs
5
+ class << self
6
+ @@jobs = []
7
+ def add(job)
8
+ @@jobs << job
9
+ end
10
+
11
+ def clean(time = 1.day.ago)
12
+ @@jobs.reject!{|j| j.created_at < time}
13
+ end
14
+
15
+ def finished_jobs
16
+ finished_jobs = @@jobs.select{|j| @@finished_statuses.include? j.status }
17
+ @@jobs -= finished_jobs
18
+ return finished_jobs
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,8 @@
1
+ module GovernorBackground
2
+ # Standard <code>Rails::Engine</code>.
3
+ class Engine < ::Rails::Engine
4
+ config.to_prepare do
5
+ ApplicationController.helper(GovernorBackgroundHelper)
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,51 @@
1
+ module Governor
2
+ module Resque
3
+ class Job
4
+ attr_reader :resource, :method_name, :created_at
5
+ def initialize(resource, method_name, job_id)
6
+ @resource = resource
7
+ @method_name = method_name
8
+ @id = job_id
9
+ @created_at = Time.now
10
+ end
11
+
12
+ def status
13
+ # if we can't find it, assume it's been killed (not really sure if this is the proper assumption)
14
+ (job = resque_status) ? job.status : 'killed'
15
+ end
16
+
17
+ def queued?
18
+ proxy :queued?
19
+ end
20
+
21
+ def working?
22
+ proxy :working?
23
+ end
24
+
25
+ def completed?
26
+ proxy :completed?
27
+ end
28
+
29
+ def failed?
30
+ proxy :failed?
31
+ end
32
+
33
+ def killed?
34
+ proxy :killed?
35
+ end
36
+
37
+ def message
38
+ proxy :message, ''
39
+ end
40
+
41
+ private
42
+ def resque_status
43
+ Resque::Status.get(@id)
44
+ end
45
+
46
+ def proxy(method, default=false)
47
+ resque_status.try(method) or default
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,12 @@
1
+ module GovernorBackground
2
+ module Resque
3
+ class Performer
4
+ @queue = :governor
5
+
6
+ def self.perform(resource, id, method_name)
7
+ article = Governor.resources[resource].to.find(id)
8
+ article.send(method_name)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,17 @@
1
+ module GovernorBackground
2
+ module Resque
3
+ class PerformerWithState < ::Resque::JobWithStatus
4
+ def self.queue
5
+ :governor
6
+ end
7
+
8
+ def perform
9
+ resource = options['resource']
10
+ id = options['id']
11
+ method_name = options['method_name']
12
+ article = Governor.resources[resource].to.find(id)
13
+ article.send(method_name)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,22 @@
1
+ require 'governor_background/rails'
2
+ require 'governor_background/handler'
3
+ require 'governor_background/job_manager'
4
+ require 'governor_background/delayed/job'
5
+ require 'governor_background/delayed/performer'
6
+ require 'governor_background/resque/job'
7
+ require 'governor_background/resque/performer'
8
+ require 'governor_background/controllers/methods'
9
+
10
+ background = Governor::Plugin.new('background')
11
+
12
+ background.register_model_callback do |base|
13
+ module InstanceMethods
14
+ private
15
+ def run_in_background(method)
16
+ GovernorBackground::Handler.run_in_background self, method
17
+ end
18
+ end
19
+ base.send :include, InstanceMethods
20
+ end
21
+
22
+ Governor::PluginManager.register background
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+
3
+ module GovernorBackground
4
+ module Delayed
5
+ describe Job do
6
+ let(:article) { Factory(:article, :author => Factory(:user)) }
7
+ it "has a status of queued if it's not currently locked" do
8
+ job = get_job_for stub(:id => article.id, :locked_at => nil)
9
+ job.should be_queued
10
+ job.status.should == 'queued'
11
+ end
12
+
13
+ it "has a status of working if it's currently locked and being run and hasn't failed" do
14
+ job = get_job_for stub(:id => article.id, :run_at => Time.now, :locked_at => Time.now, :failed? => nil)
15
+ job.should be_working
16
+ job.status.should == 'working'
17
+ end
18
+
19
+ it "has a status of completed if it can't be found" do
20
+ ::Delayed::Job.expects(:find_by_id).with(article.id).at_least_once.returns nil
21
+ job = Job.new(article, :post, stub(:id => article.id))
22
+ job.should be_completed
23
+ job.status.should == 'completed'
24
+ end
25
+
26
+ it "has a status of failed if it's marked as failed and has been run as many times as possible" do
27
+ job = get_job_for stub(:id => article.id, :run_at => Time.now, :locked_at => Time.now, :failed? => Time.now, :attempts => ::Delayed::Worker.max_attempts)
28
+ job.should be_failed
29
+ job.status.should == 'failed'
30
+ end
31
+
32
+ it "parses the message from DelayedJob" do
33
+ error_msg = "{DelayedJob error messages can be on
34
+ multiple lines"
35
+ job = get_job_for stub(:id => article.id, :run_at => Time.now, :locked_at => Time.now,
36
+ :failed? => Time.now, :attempts => ::Delayed::Worker.max_attempts, :last_error => error_msg)
37
+ job.message.should == "DelayedJob error messages can be on"
38
+ end
39
+
40
+ private
41
+ def get_job_for(delayed_job)
42
+ ::Delayed::Job.expects(:find_by_id).with(delayed_job.id).at_least_once.returns delayed_job
43
+ Job.new(article, :post, delayed_job)
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ module GovernorBackground
4
+ class Handler
5
+ cattr_writer :use_resque # programmatically prefer resque
6
+ @@use_redis = false
7
+ class << self
8
+ private
9
+ def delayed_job?
10
+ defined?(::Delayed::Job) && !@@use_resque
11
+ end
12
+ end
13
+ end
14
+
15
+ module Resque
16
+ class Job
17
+ attr_reader :resource, :method_name, :id, :created_at # make ID accessible for testing
18
+ def initialize(resource, method_name, job_id)
19
+ @resource = resource
20
+ @method_name = method_name
21
+ @id = job_id
22
+ @created_at = Time.now
23
+ end
24
+ end
25
+ end
26
+
27
+ describe Handler do
28
+ before do
29
+ JobManager.jobs.clear
30
+ @article = Factory(:article, :author => Factory(:user))
31
+ end
32
+
33
+ it "adds delayed jobs successfully" do
34
+ expect {
35
+ Handler.run_in_background(@article, :post)
36
+ }.to change { ::Delayed::Job.count }.by 1
37
+ end
38
+
39
+ it "adds resque jobs successfully" do
40
+ Handler.use_resque = true
41
+ Handler.run_in_background(@article, :post)
42
+ id = JobManager.jobs.first.id
43
+ Resque::PerformerWithState.should have_queued(id, {:resource => :articles, :id => @article.id, :method_name => :post}).in(:governor)
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+
3
+ module GovernorBackground
4
+ describe JobManager do
5
+ before(:each) do
6
+ JobManager.jobs.clear
7
+ end
8
+ it "keeps track of jobs" do
9
+ job = mock()
10
+ JobManager.add(job)
11
+ JobManager.jobs.size.should == 1
12
+ end
13
+
14
+ it "can remove old jobs" do
15
+ JobManager.add(mock(:created_at => 2.days.ago))
16
+ JobManager.add(mock(:created_at => 3.hours.ago))
17
+ JobManager.add(mock(:created_at => Time.now))
18
+ JobManager.jobs.size.should == 3
19
+ JobManager.clean
20
+ JobManager.jobs.size.should == 2
21
+ end
22
+
23
+ it "can remove old jobs specified by time" do
24
+ JobManager.add(mock(:created_at => 2.days.ago))
25
+ JobManager.add(mock(:created_at => 3.hours.ago))
26
+ JobManager.add(mock(:created_at => Time.now))
27
+ JobManager.jobs.size.should == 3
28
+ JobManager.clean(2.hours.ago)
29
+ JobManager.jobs.size.should == 1
30
+ end
31
+
32
+ it "will return all finished jobs and remove them from the list" do
33
+ JobManager.add(queued = mock('queued', :status => 'queued'))
34
+ JobManager.add(working = mock('working', :status => 'working'))
35
+ JobManager.add(completed = mock('completed', :status => 'completed'))
36
+ JobManager.add(failed = mock('failed', :status => 'failed'))
37
+ JobManager.add(killed = mock('killed', :status => 'killed'))
38
+
39
+ JobManager.jobs.size.should == 5
40
+ JobManager.finished_jobs.should == [completed, failed, killed]
41
+ JobManager.jobs.size.should == 2
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ module GovernorBackground
4
+ module Resque
5
+ describe Performer do
6
+ before do
7
+ ResqueSpec.reset!
8
+ @article = Factory(:article, :author => Factory(:user))
9
+ ::Resque.enqueue(Performer, :articles, @article.id, :post)
10
+ end
11
+
12
+ it "adds article.post to the :governor queue" do
13
+ Performer.should have_queued(:articles, @article.id, :post).in(:governor)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+ require File.expand_path('../../../../lib/governor_background/resque/performer_with_state', __FILE__)
3
+
4
+ module GovernorBackground
5
+ module Resque
6
+ describe PerformerWithState do
7
+ before do
8
+ ResqueSpec.reset!
9
+ @article = Factory(:article, :author => Factory(:user))
10
+ @id = PerformerWithState.create(:resource => :articles, :id => @article.id, :method => :post)
11
+ end
12
+
13
+ it "adds article.post to the :governor queue" do
14
+ PerformerWithState.should have_queued(@id, {:resource => :articles, :id => @article.id, :method => :post}).in(:governor)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,7 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe GovernorBackground do
4
+ it "adds #run_in_background to Article" do
5
+ Article.private_instance_methods.include? 'run_in_background'
6
+ end
7
+ end
@@ -0,0 +1,4 @@
1
+ .bundle
2
+ db/*.sqlite3
3
+ log/*.log
4
+ tmp/
@@ -0,0 +1,43 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'rails', '3.0.5'
4
+
5
+ # Bundle edge Rails instead:
6
+ # gem 'rails', :git => 'git://github.com/rails/rails.git'
7
+
8
+ gem 'sqlite3'
9
+
10
+ gem 'devise'
11
+ gem 'delayed_job'
12
+ gem 'resque', :require => 'resque/server'
13
+ gem 'resque-status', :require => 'resque/status'
14
+
15
+ gem 'governor'
16
+ gem 'governor_background', :path => '../..'
17
+
18
+ gem 'dynamic_form'
19
+
20
+ gem 'will_paginate', '~> 3.0.beta'
21
+
22
+ # Use unicorn as the web server
23
+ # gem 'unicorn'
24
+
25
+ # Deploy with Capistrano
26
+ # gem 'capistrano'
27
+
28
+ # To use debugger (ruby-debug for Ruby 1.8.7+, ruby-debug19 for Ruby 1.9.2+)
29
+ # gem 'ruby-debug'
30
+ # gem 'ruby-debug19', :require => 'ruby-debug'
31
+
32
+ # Bundle the extra gems:
33
+ # gem 'bj'
34
+ # gem 'nokogiri'
35
+ # gem 'sqlite3-ruby', :require => 'sqlite3'
36
+ # gem 'aws-s3', :require => 'aws/s3'
37
+
38
+ # Bundle gems for the local environment. Make sure to
39
+ # put test-only gems in this group so their generators
40
+ # and rake tasks are available in development mode:
41
+ # group :development, :test do
42
+ # gem 'webrat'
43
+ # end
@@ -0,0 +1,128 @@
1
+ PATH
2
+ remote: ../..
3
+ specs:
4
+ governor_background (0.0.0)
5
+ governor
6
+
7
+ GEM
8
+ remote: http://rubygems.org/
9
+ specs:
10
+ abstract (1.0.0)
11
+ actionmailer (3.0.5)
12
+ actionpack (= 3.0.5)
13
+ mail (~> 2.2.15)
14
+ actionpack (3.0.5)
15
+ activemodel (= 3.0.5)
16
+ activesupport (= 3.0.5)
17
+ builder (~> 2.1.2)
18
+ erubis (~> 2.6.6)
19
+ i18n (~> 0.4)
20
+ rack (~> 1.2.1)
21
+ rack-mount (~> 0.6.13)
22
+ rack-test (~> 0.5.7)
23
+ tzinfo (~> 0.3.23)
24
+ activemodel (3.0.5)
25
+ activesupport (= 3.0.5)
26
+ builder (~> 2.1.2)
27
+ i18n (~> 0.4)
28
+ activerecord (3.0.5)
29
+ activemodel (= 3.0.5)
30
+ activesupport (= 3.0.5)
31
+ arel (~> 2.0.2)
32
+ tzinfo (~> 0.3.23)
33
+ activeresource (3.0.5)
34
+ activemodel (= 3.0.5)
35
+ activesupport (= 3.0.5)
36
+ activesupport (3.0.5)
37
+ arel (2.0.9)
38
+ bcrypt-ruby (2.1.4)
39
+ builder (2.1.2)
40
+ daemons (1.1.2)
41
+ delayed_job (2.1.4)
42
+ activesupport (~> 3.0)
43
+ daemons
44
+ devise (1.3.1)
45
+ bcrypt-ruby (~> 2.1.2)
46
+ orm_adapter (~> 0.0.3)
47
+ warden (~> 1.0.3)
48
+ dynamic_form (1.1.4)
49
+ erubis (2.6.6)
50
+ abstract (>= 1.0.0)
51
+ governor (0.3.0)
52
+ rails (~> 3.0.5)
53
+ i18n (0.5.0)
54
+ json (1.4.6)
55
+ macaddr (1.0.0)
56
+ mail (2.2.17)
57
+ activesupport (>= 2.3.6)
58
+ i18n (>= 0.4.0)
59
+ mime-types (~> 1.16)
60
+ treetop (~> 1.4.8)
61
+ mime-types (1.16)
62
+ orm_adapter (0.0.4)
63
+ polyglot (0.3.1)
64
+ rack (1.2.2)
65
+ rack-mount (0.6.14)
66
+ rack (>= 1.0.0)
67
+ rack-test (0.5.7)
68
+ rack (>= 1.0)
69
+ rails (3.0.5)
70
+ actionmailer (= 3.0.5)
71
+ actionpack (= 3.0.5)
72
+ activerecord (= 3.0.5)
73
+ activeresource (= 3.0.5)
74
+ activesupport (= 3.0.5)
75
+ bundler (~> 1.0)
76
+ railties (= 3.0.5)
77
+ railties (3.0.5)
78
+ actionpack (= 3.0.5)
79
+ activesupport (= 3.0.5)
80
+ rake (>= 0.8.7)
81
+ thor (~> 0.14.4)
82
+ rake (0.8.7)
83
+ redis (2.2.0)
84
+ redis-namespace (0.10.0)
85
+ redis (< 3.0.0)
86
+ redisk (0.2.2)
87
+ redis (>= 0.1.1)
88
+ redis-namespace (>= 0.1.0)
89
+ resque (1.15.0)
90
+ json (~> 1.4.6)
91
+ redis-namespace (>= 0.10.0)
92
+ sinatra (>= 0.9.2)
93
+ vegas (~> 0.1.2)
94
+ resque-status (0.2.3)
95
+ redisk (>= 0.2.1)
96
+ resque (>= 1.3.1)
97
+ uuid (>= 2.0.2)
98
+ sinatra (1.2.3)
99
+ rack (~> 1.1)
100
+ tilt (>= 1.2.2, < 2.0)
101
+ sqlite3 (1.3.3)
102
+ thor (0.14.6)
103
+ tilt (1.2.2)
104
+ treetop (1.4.9)
105
+ polyglot (>= 0.3.1)
106
+ tzinfo (0.3.26)
107
+ uuid (2.3.2)
108
+ macaddr (~> 1.0)
109
+ vegas (0.1.8)
110
+ rack (>= 1.0.0)
111
+ warden (1.0.3)
112
+ rack (>= 1.0.0)
113
+ will_paginate (3.0.pre2)
114
+
115
+ PLATFORMS
116
+ ruby
117
+
118
+ DEPENDENCIES
119
+ delayed_job
120
+ devise
121
+ dynamic_form
122
+ governor
123
+ governor_background!
124
+ rails (= 3.0.5)
125
+ resque
126
+ resque-status
127
+ sqlite3
128
+ will_paginate (~> 3.0.beta)