delayed_job_groups 0.2.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/.gitignore +4 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +106 -0
- data/README.markdown +78 -0
- data/Rakefile.rb +17 -0
- data/VERSION +1 -0
- data/delayed_job_groups.gemspec +53 -0
- data/lib/delayed_job_groups/active_record_groups.rb +23 -0
- data/lib/delayed_job_groups/delayed_job_groups.rb +14 -0
- data/lib/delayed_job_groups.rb +2 -0
- data/spec/database.yml +3 -0
- data/spec/delayed_job_groups_spec.rb +93 -0
- data/spec/spec_helper.rb +56 -0
- metadata +80 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
GIT
|
2
|
+
remote: http://github.com/collectiveidea/delayed_job.git
|
3
|
+
revision: aba9905764c2a13a110a272137d1ad9798fd55e0
|
4
|
+
specs:
|
5
|
+
delayed_job (2.1.0.pre2)
|
6
|
+
activesupport (~> 3.0)
|
7
|
+
daemons
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: http://rubygems.org/
|
11
|
+
specs:
|
12
|
+
abstract (1.0.0)
|
13
|
+
actionmailer (3.0.1)
|
14
|
+
actionpack (= 3.0.1)
|
15
|
+
mail (~> 2.2.5)
|
16
|
+
actionpack (3.0.1)
|
17
|
+
activemodel (= 3.0.1)
|
18
|
+
activesupport (= 3.0.1)
|
19
|
+
builder (~> 2.1.2)
|
20
|
+
erubis (~> 2.6.6)
|
21
|
+
i18n (~> 0.4.1)
|
22
|
+
rack (~> 1.2.1)
|
23
|
+
rack-mount (~> 0.6.12)
|
24
|
+
rack-test (~> 0.5.4)
|
25
|
+
tzinfo (~> 0.3.23)
|
26
|
+
activemodel (3.0.1)
|
27
|
+
activesupport (= 3.0.1)
|
28
|
+
builder (~> 2.1.2)
|
29
|
+
i18n (~> 0.4.1)
|
30
|
+
activerecord (3.0.1)
|
31
|
+
activemodel (= 3.0.1)
|
32
|
+
activesupport (= 3.0.1)
|
33
|
+
arel (~> 1.0.0)
|
34
|
+
tzinfo (~> 0.3.23)
|
35
|
+
activeresource (3.0.1)
|
36
|
+
activemodel (= 3.0.1)
|
37
|
+
activesupport (= 3.0.1)
|
38
|
+
activesupport (3.0.1)
|
39
|
+
arel (1.0.1)
|
40
|
+
activesupport (~> 3.0.0)
|
41
|
+
autotest (4.4.1)
|
42
|
+
autotest-fsevent (0.2.3)
|
43
|
+
sys-uname
|
44
|
+
autotest-growl (0.2.6)
|
45
|
+
builder (2.1.2)
|
46
|
+
daemons (1.1.0)
|
47
|
+
diff-lcs (1.1.2)
|
48
|
+
erubis (2.6.6)
|
49
|
+
abstract (>= 1.0.0)
|
50
|
+
i18n (0.4.2)
|
51
|
+
mail (2.2.9)
|
52
|
+
activesupport (>= 2.3.6)
|
53
|
+
i18n (~> 0.4.1)
|
54
|
+
mime-types (~> 1.16)
|
55
|
+
treetop (~> 1.4.8)
|
56
|
+
mime-types (1.16)
|
57
|
+
polyglot (0.3.1)
|
58
|
+
rack (1.2.1)
|
59
|
+
rack-mount (0.6.13)
|
60
|
+
rack (>= 1.0.0)
|
61
|
+
rack-test (0.5.6)
|
62
|
+
rack (>= 1.0)
|
63
|
+
rails (3.0.1)
|
64
|
+
actionmailer (= 3.0.1)
|
65
|
+
actionpack (= 3.0.1)
|
66
|
+
activerecord (= 3.0.1)
|
67
|
+
activeresource (= 3.0.1)
|
68
|
+
activesupport (= 3.0.1)
|
69
|
+
bundler (~> 1.0.0)
|
70
|
+
railties (= 3.0.1)
|
71
|
+
railties (3.0.1)
|
72
|
+
actionpack (= 3.0.1)
|
73
|
+
activesupport (= 3.0.1)
|
74
|
+
rake (>= 0.8.4)
|
75
|
+
thor (~> 0.14.0)
|
76
|
+
rake (0.8.7)
|
77
|
+
rspec (2.0.1)
|
78
|
+
rspec-core (~> 2.0.1)
|
79
|
+
rspec-expectations (~> 2.0.1)
|
80
|
+
rspec-mocks (~> 2.0.1)
|
81
|
+
rspec-core (2.0.1)
|
82
|
+
rspec-expectations (2.0.1)
|
83
|
+
diff-lcs (>= 1.1.2)
|
84
|
+
rspec-mocks (2.0.1)
|
85
|
+
rspec-core (~> 2.0.1)
|
86
|
+
rspec-expectations (~> 2.0.1)
|
87
|
+
rspec-rails (2.0.1)
|
88
|
+
rspec (~> 2.0.0)
|
89
|
+
sqlite3-ruby (1.3.1)
|
90
|
+
sys-uname (0.8.4)
|
91
|
+
thor (0.14.3)
|
92
|
+
treetop (1.4.8)
|
93
|
+
polyglot (>= 0.3.1)
|
94
|
+
tzinfo (0.3.23)
|
95
|
+
|
96
|
+
PLATFORMS
|
97
|
+
ruby
|
98
|
+
|
99
|
+
DEPENDENCIES
|
100
|
+
autotest
|
101
|
+
autotest-fsevent
|
102
|
+
autotest-growl
|
103
|
+
delayed_job!
|
104
|
+
rails
|
105
|
+
rspec-rails
|
106
|
+
sqlite3-ruby
|
data/README.markdown
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
delayed job groups
|
2
|
+
==================
|
3
|
+
|
4
|
+
Adds grouping to jobs. Only 1 job in each group will be executed regardless of the number of workers.
|
5
|
+
|
6
|
+
|
7
|
+
Requires
|
8
|
+
--------
|
9
|
+
|
10
|
+
* rails 3
|
11
|
+
* Latest version of delayed_job from github - current release(v2.1.0.pre2) does not support enqueue hooks
|
12
|
+
* active_record backend - other backends aren't supported'
|
13
|
+
|
14
|
+
|
15
|
+
Install
|
16
|
+
-------
|
17
|
+
|
18
|
+
# Gemfile
|
19
|
+
gem 'delayed_job_groups', :require => false
|
20
|
+
|
21
|
+
# application.rb
|
22
|
+
AppName::Application.initialize!
|
23
|
+
require 'delayed_job_groups; # must be loaded after delayed job has guessed backend
|
24
|
+
|
25
|
+
Add migration to add lock_group column
|
26
|
+
|
27
|
+
# db/migrate/xxx_add_lock_group_to_delayed_jobs
|
28
|
+
class AddLockGroupToDelayedJobs < ActiveRecord::Migration
|
29
|
+
def self.up
|
30
|
+
add_column :delayed_jobs, :lock_group, :string
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.down
|
34
|
+
remove_column :delayed_jobs, :lock_group
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
Usage
|
40
|
+
-----
|
41
|
+
|
42
|
+
Job groups are strings. You need to specify what the job_group should be in a block. Delayed job will only perform 1 job from each group at a time.
|
43
|
+
|
44
|
+
### Job groups for standard jobs ###
|
45
|
+
|
46
|
+
class ResizeImageJob < Struct.new(:format)
|
47
|
+
job_group{ |resize_image_job| resize_image_job.format }
|
48
|
+
|
49
|
+
def perform
|
50
|
+
resize_to format
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
### Job groups when using delay() ###
|
56
|
+
|
57
|
+
class Person < ActiveRecord::Base
|
58
|
+
job_group{ |person| person.role }
|
59
|
+
|
60
|
+
def send_welcome
|
61
|
+
...
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
Person.create(:role => "admin").delay.send_welcome
|
66
|
+
|
67
|
+
### Job groups when methods are declared asynchonous ###
|
68
|
+
|
69
|
+
class Person < ActiveRecord::Base
|
70
|
+
job_group{ |person| person.role }
|
71
|
+
|
72
|
+
def send_welcome
|
73
|
+
...
|
74
|
+
end
|
75
|
+
handle_asynchronously :send_welcome
|
76
|
+
end
|
77
|
+
|
78
|
+
Person.create(:role => "admin").send_welcome
|
data/Rakefile.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "delayed_job_groups"
|
8
|
+
gem.summary = %Q{Adds job groups to delayed_job}
|
9
|
+
gem.description = %Q{Adds job groups to delayed_job}
|
10
|
+
gem.email = "oliver@opsb.co.uk"
|
11
|
+
gem.homepage = "http://github.com/opsb/delayed_job_groups"
|
12
|
+
gem.authors = ["opsb"]
|
13
|
+
end
|
14
|
+
Jeweler::GemcutterTasks.new
|
15
|
+
rescue LoadError
|
16
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
17
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile.rb, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{delayed_job_groups}
|
8
|
+
s.version = "0.2.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["opsb"]
|
12
|
+
s.date = %q{2010-11-02}
|
13
|
+
s.description = %q{Adds job groups to delayed_job}
|
14
|
+
s.email = %q{oliver@opsb.co.uk}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"README.markdown"
|
17
|
+
]
|
18
|
+
s.files = [
|
19
|
+
".gitignore",
|
20
|
+
"Gemfile",
|
21
|
+
"Gemfile.lock",
|
22
|
+
"README.markdown",
|
23
|
+
"Rakefile.rb",
|
24
|
+
"VERSION",
|
25
|
+
"delayed_job_groups.gemspec",
|
26
|
+
"lib/delayed_job_groups.rb",
|
27
|
+
"lib/delayed_job_groups/active_record_groups.rb",
|
28
|
+
"lib/delayed_job_groups/delayed_job_groups.rb",
|
29
|
+
"spec/database.yml",
|
30
|
+
"spec/delayed_job_groups_spec.rb",
|
31
|
+
"spec/spec_helper.rb"
|
32
|
+
]
|
33
|
+
s.homepage = %q{http://github.com/opsb/delayed_job_groups}
|
34
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
35
|
+
s.require_paths = ["lib"]
|
36
|
+
s.rubygems_version = %q{1.3.7}
|
37
|
+
s.summary = %q{Adds job groups to delayed_job}
|
38
|
+
s.test_files = [
|
39
|
+
"spec/delayed_job_groups_spec.rb",
|
40
|
+
"spec/spec_helper.rb"
|
41
|
+
]
|
42
|
+
|
43
|
+
if s.respond_to? :specification_version then
|
44
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
45
|
+
s.specification_version = 3
|
46
|
+
|
47
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
48
|
+
else
|
49
|
+
end
|
50
|
+
else
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class ActiveRecord::Base
|
2
|
+
class << self
|
3
|
+
def job_group(&block)
|
4
|
+
@lock_group_factory = block
|
5
|
+
end
|
6
|
+
|
7
|
+
def has_job_groups?
|
8
|
+
!!@lock_group_factory
|
9
|
+
end
|
10
|
+
|
11
|
+
def lock_group(payload)
|
12
|
+
@lock_group_factory.call(payload)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def enqueue(job)
|
17
|
+
target = job.payload_object.class == ::Delayed::PerformableMethod ? job.payload_object.object : job.payload_object
|
18
|
+
if target.class.has_job_groups?
|
19
|
+
job.lock_group = target.class.lock_group(target)
|
20
|
+
job.save
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'delayed_job'
|
2
|
+
|
3
|
+
class Delayed::Backend::ActiveRecord::Job
|
4
|
+
scope :in_unlocked_group, lambda{
|
5
|
+
delayed_jobs = self.table_name
|
6
|
+
unlocked_groups_select = "select distinct #{delayed_jobs}.lock_group from #{delayed_jobs} where #{delayed_jobs}.locked_by is not null"
|
7
|
+
where("#{delayed_jobs}.lock_group not in (#{unlocked_groups_select}) or #{delayed_jobs}.lock_group is null")
|
8
|
+
}
|
9
|
+
scope :orig_ready_to_run, scopes[:ready_to_run]
|
10
|
+
scope :ready_to_run, lambda{ |*args|
|
11
|
+
orig_ready_to_run(*args).
|
12
|
+
in_unlocked_group
|
13
|
+
}
|
14
|
+
end
|
data/spec/database.yml
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
|
3
|
+
ActiveRecord::Schema.define do
|
4
|
+
create_table :grouped_jobs, :force => true do |table|
|
5
|
+
table.string :repository
|
6
|
+
end
|
7
|
+
create_table :simple_jobs, :force => true do |table|
|
8
|
+
end
|
9
|
+
create_table :users, :force => true do |table|
|
10
|
+
table.string :role
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class GroupedJob < ActiveRecord::Base
|
15
|
+
job_group{ |simple_job| simple_job.repository }
|
16
|
+
|
17
|
+
def perform
|
18
|
+
puts "running grouped job"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class SimpleJob < ActiveRecord::Base
|
23
|
+
def perform
|
24
|
+
puts "running simple job"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class User < ActiveRecord::Base
|
29
|
+
job_group{ |user| user.role }
|
30
|
+
def send_welcome_email
|
31
|
+
puts "thanking user"
|
32
|
+
end
|
33
|
+
handle_asynchronously :send_welcome_email
|
34
|
+
def expensive_operation
|
35
|
+
puts "working hard"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe Delayed::Job do
|
40
|
+
MAX_RUN_TIME = 4000 # seconds? TBC
|
41
|
+
WORKER = 'name_of_worker'
|
42
|
+
|
43
|
+
context "with 2 jobs in the same group, one locked, one unlocked and 1 job in a different group" do
|
44
|
+
before do
|
45
|
+
2.times{ Delayed::Job.enqueue GroupedJob.new(:repository => "repo1") }
|
46
|
+
1.times{ Delayed::Job.enqueue GroupedJob.new(:repository => "repo2") }
|
47
|
+
Delayed::Job.first.lock_exclusively!(MAX_RUN_TIME, WORKER)
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should find no jobs that are ready to run" do
|
51
|
+
Delayed::Job.ready_to_run(WORKER, MAX_RUN_TIME).count.should == 1
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context "job with no group" do
|
56
|
+
before do
|
57
|
+
Delayed::Job.enqueue SimpleJob.new
|
58
|
+
end
|
59
|
+
it "should still be queuable" do
|
60
|
+
Delayed::Job.ready_to_run(WORKER, MAX_RUN_TIME).count.should == 1
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context "with 2 jobs in the same group, from methods declared as asynchronous, one unlocked and 1 job in a different group" do
|
65
|
+
before do
|
66
|
+
2.times do
|
67
|
+
User.create(:role => "admin").send_welcome_email
|
68
|
+
end
|
69
|
+
1.times{ Delayed::Job.enqueue GroupedJob.new(:repository => "repo2") }
|
70
|
+
Delayed::Job.first.lock_exclusively!(MAX_RUN_TIME, WORKER)
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should find no jobs that are ready to run" do
|
75
|
+
Delayed::Job.ready_to_run(WORKER, MAX_RUN_TIME).count.should == 1
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context "with 2 jobs in the same group, from delay() calls, one unlocked and 1 job in a different group" do
|
80
|
+
before do
|
81
|
+
2.times do
|
82
|
+
User.create(:role => "admin").delay.expensive_operation
|
83
|
+
end
|
84
|
+
1.times{ Delayed::Job.enqueue GroupedJob.new(:repository => "repo2") }
|
85
|
+
Delayed::Job.first.lock_exclusively!(MAX_RUN_TIME, WORKER)
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should find no jobs that are ready to run" do
|
90
|
+
Delayed::Job.ready_to_run(WORKER, MAX_RUN_TIME).count.should == 1
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler/setup'
|
5
|
+
require 'logger'
|
6
|
+
|
7
|
+
|
8
|
+
|
9
|
+
ENV['RAILS_ENV'] = 'test'
|
10
|
+
require 'rails'
|
11
|
+
|
12
|
+
require 'active_record'
|
13
|
+
config = YAML.load(File.read('spec/database.yml'))
|
14
|
+
ActiveRecord::Base.configurations = {'test' => config['sqlite']}
|
15
|
+
ActiveRecord::Base.establish_connection
|
16
|
+
ActiveRecord::Migration.verbose = false
|
17
|
+
|
18
|
+
ActiveRecord::Schema.define do
|
19
|
+
create_table :delayed_jobs, :force => true do |table|
|
20
|
+
table.integer :priority, :default => 0
|
21
|
+
table.integer :attempts, :default => 0
|
22
|
+
table.text :handler
|
23
|
+
table.text :last_error
|
24
|
+
table.datetime :run_at
|
25
|
+
table.datetime :locked_at
|
26
|
+
table.datetime :failed_at
|
27
|
+
table.string :locked_by
|
28
|
+
table.string :lock_group
|
29
|
+
table.timestamps
|
30
|
+
|
31
|
+
table.integer :queue_id
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
require 'rspec'
|
36
|
+
require 'delayed_job'
|
37
|
+
|
38
|
+
Delayed::Worker.logger = Logger.new('/tmp/dj.log')
|
39
|
+
ActiveRecord::Base.logger = Delayed::Worker.logger
|
40
|
+
Delayed::Worker.backend = :active_record
|
41
|
+
|
42
|
+
require 'delayed_job_groups'
|
43
|
+
RSpec.configure do |config|
|
44
|
+
config.before do
|
45
|
+
ActiveRecord::Base.connection.increment_open_transactions
|
46
|
+
ActiveRecord::Base.connection.transaction_joinable = false
|
47
|
+
ActiveRecord::Base.connection.begin_db_transaction
|
48
|
+
end
|
49
|
+
config.after do
|
50
|
+
if ActiveRecord::Base.connection.open_transactions != 0
|
51
|
+
ActiveRecord::Base.connection.rollback_db_transaction
|
52
|
+
ActiveRecord::Base.connection.decrement_open_transactions
|
53
|
+
end
|
54
|
+
ActiveRecord::Base.clear_active_connections!
|
55
|
+
end
|
56
|
+
end
|
metadata
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: delayed_job_groups
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 23
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 2
|
9
|
+
- 0
|
10
|
+
version: 0.2.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- opsb
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-11-02 00:00:00 +00:00
|
19
|
+
default_executable:
|
20
|
+
dependencies: []
|
21
|
+
|
22
|
+
description: Adds job groups to delayed_job
|
23
|
+
email: oliver@opsb.co.uk
|
24
|
+
executables: []
|
25
|
+
|
26
|
+
extensions: []
|
27
|
+
|
28
|
+
extra_rdoc_files:
|
29
|
+
- README.markdown
|
30
|
+
files:
|
31
|
+
- .gitignore
|
32
|
+
- Gemfile
|
33
|
+
- Gemfile.lock
|
34
|
+
- README.markdown
|
35
|
+
- Rakefile.rb
|
36
|
+
- VERSION
|
37
|
+
- delayed_job_groups.gemspec
|
38
|
+
- lib/delayed_job_groups.rb
|
39
|
+
- lib/delayed_job_groups/active_record_groups.rb
|
40
|
+
- lib/delayed_job_groups/delayed_job_groups.rb
|
41
|
+
- spec/database.yml
|
42
|
+
- spec/delayed_job_groups_spec.rb
|
43
|
+
- spec/spec_helper.rb
|
44
|
+
has_rdoc: true
|
45
|
+
homepage: http://github.com/opsb/delayed_job_groups
|
46
|
+
licenses: []
|
47
|
+
|
48
|
+
post_install_message:
|
49
|
+
rdoc_options:
|
50
|
+
- --charset=UTF-8
|
51
|
+
require_paths:
|
52
|
+
- lib
|
53
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
hash: 3
|
59
|
+
segments:
|
60
|
+
- 0
|
61
|
+
version: "0"
|
62
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
hash: 3
|
68
|
+
segments:
|
69
|
+
- 0
|
70
|
+
version: "0"
|
71
|
+
requirements: []
|
72
|
+
|
73
|
+
rubyforge_project:
|
74
|
+
rubygems_version: 1.3.7
|
75
|
+
signing_key:
|
76
|
+
specification_version: 3
|
77
|
+
summary: Adds job groups to delayed_job
|
78
|
+
test_files:
|
79
|
+
- spec/delayed_job_groups_spec.rb
|
80
|
+
- spec/spec_helper.rb
|