opsb-delayed_job 2.0.3
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 +2 -0
- data/MIT-LICENSE +20 -0
- data/README.textile +213 -0
- data/Rakefile +46 -0
- data/VERSION +1 -0
- data/benchmarks.rb +33 -0
- data/contrib/delayed_job.monitrc +14 -0
- data/contrib/delayed_job_multiple.monitrc +23 -0
- data/delayed_job.gemspec +115 -0
- data/generators/delayed_job/delayed_job_generator.rb +22 -0
- data/generators/delayed_job/templates/migration.rb +21 -0
- data/generators/delayed_job/templates/script +5 -0
- data/init.rb +1 -0
- data/lib/delayed/backend/active_record.rb +90 -0
- data/lib/delayed/backend/base.rb +111 -0
- data/lib/delayed/backend/data_mapper.rb +125 -0
- data/lib/delayed/backend/mongo_mapper.rb +110 -0
- data/lib/delayed/command.rb +101 -0
- data/lib/delayed/message_sending.rb +22 -0
- data/lib/delayed/performable_method.rb +62 -0
- data/lib/delayed/railtie.rb +10 -0
- data/lib/delayed/recipes.rb +31 -0
- data/lib/delayed/tasks.rb +15 -0
- data/lib/delayed/worker.rb +183 -0
- data/lib/delayed_job.rb +14 -0
- data/rails/init.rb +5 -0
- data/recipes/delayed_job.rb +1 -0
- data/spec/backend/active_record_job_spec.rb +46 -0
- data/spec/backend/data_mapper_job_spec.rb +16 -0
- data/spec/backend/mongo_mapper_job_spec.rb +94 -0
- data/spec/backend/shared_backend_spec.rb +265 -0
- data/spec/delayed_method_spec.rb +59 -0
- data/spec/performable_method_spec.rb +42 -0
- data/spec/sample_jobs.rb +25 -0
- data/spec/setup/active_record.rb +33 -0
- data/spec/setup/data_mapper.rb +8 -0
- data/spec/setup/mongo_mapper.rb +17 -0
- data/spec/spec_helper.rb +26 -0
- data/spec/story_spec.rb +17 -0
- data/spec/worker_spec.rb +216 -0
- data/tasks/jobs.rake +1 -0
- metadata +256 -0
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class StoryReader
|
4
|
+
def read(story)
|
5
|
+
"Epilog: #{story.tell}"
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
describe Delayed::PerformableMethod do
|
10
|
+
|
11
|
+
it "should ignore ActiveRecord::RecordNotFound errors because they are permanent" do
|
12
|
+
story = Story.create :text => 'Once upon...'
|
13
|
+
p = Delayed::PerformableMethod.new(story, :tell, [])
|
14
|
+
story.destroy
|
15
|
+
lambda { p.perform }.should_not raise_error
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should store the object as string if its an active record" do
|
19
|
+
story = Story.create :text => 'Once upon...'
|
20
|
+
p = Delayed::PerformableMethod.new(story, :tell, [])
|
21
|
+
p.class.should == Delayed::PerformableMethod
|
22
|
+
p.object.should == "LOAD;Story;#{story.id}"
|
23
|
+
p.method.should == :tell
|
24
|
+
p.args.should == []
|
25
|
+
p.perform.should == 'Once upon...'
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should allow class methods to be called on ActiveRecord models" do
|
29
|
+
p = Delayed::PerformableMethod.new(Story, :count, [])
|
30
|
+
lambda { p.send(:load, p.object) }.should_not raise_error
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should store arguments as string if they are active record objects" do
|
34
|
+
story = Story.create :text => 'Once upon...'
|
35
|
+
reader = StoryReader.new
|
36
|
+
p = Delayed::PerformableMethod.new(reader, :read, [story])
|
37
|
+
p.class.should == Delayed::PerformableMethod
|
38
|
+
p.method.should == :read
|
39
|
+
p.args.should == ["LOAD;Story;#{story.id}"]
|
40
|
+
p.perform.should == 'Epilog: Once upon...'
|
41
|
+
end
|
42
|
+
end
|
data/spec/sample_jobs.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
class SimpleJob
|
2
|
+
cattr_accessor :runs; self.runs = 0
|
3
|
+
def perform; @@runs += 1; end
|
4
|
+
end
|
5
|
+
|
6
|
+
class ErrorJob
|
7
|
+
cattr_accessor :runs; self.runs = 0
|
8
|
+
def perform; raise 'did not work'; end
|
9
|
+
end
|
10
|
+
|
11
|
+
class LongRunningJob
|
12
|
+
def perform; sleep 250; end
|
13
|
+
end
|
14
|
+
|
15
|
+
class OnPermanentFailureJob < SimpleJob
|
16
|
+
def on_permanent_failure
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
module M
|
21
|
+
class ModuleJob
|
22
|
+
cattr_accessor :runs; self.runs = 0
|
23
|
+
def perform; @@runs += 1; end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
|
3
|
+
ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => ':memory:')
|
4
|
+
ActiveRecord::Base.logger = Delayed::Worker.logger
|
5
|
+
ActiveRecord::Migration.verbose = false
|
6
|
+
|
7
|
+
ActiveRecord::Schema.define do
|
8
|
+
create_table :delayed_jobs, :force => true do |table|
|
9
|
+
table.integer :priority, :default => 0
|
10
|
+
table.integer :attempts, :default => 0
|
11
|
+
table.text :handler
|
12
|
+
table.text :last_error
|
13
|
+
table.datetime :run_at
|
14
|
+
table.datetime :locked_at
|
15
|
+
table.datetime :failed_at
|
16
|
+
table.string :locked_by
|
17
|
+
table.timestamps
|
18
|
+
end
|
19
|
+
|
20
|
+
add_index :delayed_jobs, [:priority, :run_at], :name => 'delayed_jobs_priority'
|
21
|
+
|
22
|
+
create_table :stories, :force => true do |table|
|
23
|
+
table.string :text
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Purely useful for test cases...
|
28
|
+
class Story < ActiveRecord::Base
|
29
|
+
def tell; text; end
|
30
|
+
def whatever(n, _); tell*n; end
|
31
|
+
|
32
|
+
handle_asynchronously :whatever
|
33
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'mongo_mapper'
|
2
|
+
|
3
|
+
MongoMapper.config = {
|
4
|
+
RAILS_ENV => {'database' => 'delayed_job'}
|
5
|
+
}
|
6
|
+
MongoMapper.connect RAILS_ENV
|
7
|
+
|
8
|
+
unless defined?(Story)
|
9
|
+
class Story
|
10
|
+
include ::MongoMapper::Document
|
11
|
+
def tell; text; end
|
12
|
+
def whatever(n, _); tell*n; end
|
13
|
+
def self.count; end
|
14
|
+
|
15
|
+
handle_asynchronously :whatever
|
16
|
+
end
|
17
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'spec'
|
5
|
+
require 'logger'
|
6
|
+
|
7
|
+
require 'delayed_job'
|
8
|
+
require 'sample_jobs'
|
9
|
+
|
10
|
+
Delayed::Worker.logger = Logger.new('/tmp/dj.log')
|
11
|
+
RAILS_ENV = 'test'
|
12
|
+
|
13
|
+
# determine the available backends
|
14
|
+
BACKENDS = []
|
15
|
+
Dir.glob("#{File.dirname(__FILE__)}/setup/*.rb") do |backend|
|
16
|
+
begin
|
17
|
+
backend = File.basename(backend, '.rb')
|
18
|
+
require "setup/#{backend}"
|
19
|
+
require "backend/#{backend}_job_spec"
|
20
|
+
BACKENDS << backend.to_sym
|
21
|
+
rescue LoadError
|
22
|
+
puts "Unable to load #{backend} backend! #{$!}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
Delayed::Worker.backend = BACKENDS.first
|
data/spec/story_spec.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "A story" do
|
4
|
+
|
5
|
+
before(:all) do
|
6
|
+
@story = Story.create :text => "Once upon a time..."
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should be shared" do
|
10
|
+
@story.tell.should == 'Once upon a time...'
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should not return its result if it storytelling is delayed" do
|
14
|
+
@story.send_later(:tell).should_not == 'Once upon a time...'
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
data/spec/worker_spec.rb
ADDED
@@ -0,0 +1,216 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Delayed::Worker do
|
4
|
+
def job_create(opts = {})
|
5
|
+
Delayed::Job.create(opts.merge(:payload_object => SimpleJob.new))
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "backend=" do
|
9
|
+
it "should set the Delayed::Job constant to the backend" do
|
10
|
+
@clazz = Class.new
|
11
|
+
Delayed::Worker.backend = @clazz
|
12
|
+
Delayed::Job.should == @clazz
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should set backend with a symbol" do
|
16
|
+
Delayed::Worker.backend = Class.new
|
17
|
+
Delayed::Worker.backend = :active_record
|
18
|
+
Delayed::Worker.backend.should == Delayed::Backend::ActiveRecord::Job
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
BACKENDS.each do |backend|
|
23
|
+
describe "with the #{backend} backend" do
|
24
|
+
before do
|
25
|
+
Delayed::Worker.backend = backend
|
26
|
+
Delayed::Job.delete_all
|
27
|
+
|
28
|
+
@worker = Delayed::Worker.new(:max_priority => nil, :min_priority => nil, :quiet => true)
|
29
|
+
|
30
|
+
SimpleJob.runs = 0
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "running a job" do
|
34
|
+
it "should fail after Worker.max_run_time" do
|
35
|
+
begin
|
36
|
+
old_max_run_time = Delayed::Worker.max_run_time
|
37
|
+
Delayed::Worker.max_run_time = 1.second
|
38
|
+
@job = Delayed::Job.create :payload_object => LongRunningJob.new
|
39
|
+
@worker.run(@job)
|
40
|
+
@job.reload.last_error.should =~ /expired/
|
41
|
+
@job.attempts.should == 1
|
42
|
+
ensure
|
43
|
+
Delayed::Worker.max_run_time = old_max_run_time
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context "worker prioritization" do
|
49
|
+
before(:each) do
|
50
|
+
@worker = Delayed::Worker.new(:max_priority => 5, :min_priority => -5, :quiet => true)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should only work_off jobs that are >= min_priority" do
|
54
|
+
SimpleJob.runs.should == 0
|
55
|
+
|
56
|
+
job_create(:priority => -10)
|
57
|
+
job_create(:priority => 0)
|
58
|
+
@worker.work_off
|
59
|
+
|
60
|
+
SimpleJob.runs.should == 1
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should only work_off jobs that are <= max_priority" do
|
64
|
+
SimpleJob.runs.should == 0
|
65
|
+
|
66
|
+
job_create(:priority => 10)
|
67
|
+
job_create(:priority => 0)
|
68
|
+
|
69
|
+
@worker.work_off
|
70
|
+
|
71
|
+
SimpleJob.runs.should == 1
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context "while running with locked and expired jobs" do
|
76
|
+
before(:each) do
|
77
|
+
@worker.name = 'worker1'
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should not run jobs locked by another worker" do
|
81
|
+
job_create(:locked_by => 'other_worker', :locked_at => (Delayed::Job.db_time_now - 1.minutes))
|
82
|
+
lambda { @worker.work_off }.should_not change { SimpleJob.runs }
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should run open jobs" do
|
86
|
+
job_create
|
87
|
+
lambda { @worker.work_off }.should change { SimpleJob.runs }.from(0).to(1)
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should run expired jobs" do
|
91
|
+
expired_time = Delayed::Job.db_time_now - (1.minutes + Delayed::Worker.max_run_time)
|
92
|
+
job_create(:locked_by => 'other_worker', :locked_at => expired_time)
|
93
|
+
lambda { @worker.work_off }.should change { SimpleJob.runs }.from(0).to(1)
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should run own jobs" do
|
97
|
+
job_create(:locked_by => @worker.name, :locked_at => (Delayed::Job.db_time_now - 1.minutes))
|
98
|
+
lambda { @worker.work_off }.should change { SimpleJob.runs }.from(0).to(1)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe "failed jobs" do
|
103
|
+
before do
|
104
|
+
# reset defaults
|
105
|
+
Delayed::Worker.destroy_failed_jobs = true
|
106
|
+
Delayed::Worker.max_attempts = 25
|
107
|
+
|
108
|
+
@job = Delayed::Job.enqueue ErrorJob.new
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should record last_error when destroy_failed_jobs = false, max_attempts = 1" do
|
112
|
+
Delayed::Worker.destroy_failed_jobs = false
|
113
|
+
Delayed::Worker.max_attempts = 1
|
114
|
+
@worker.run(@job)
|
115
|
+
@job.reload
|
116
|
+
@job.last_error.should =~ /did not work/
|
117
|
+
@job.last_error.should =~ /worker_spec.rb/
|
118
|
+
@job.attempts.should == 1
|
119
|
+
@job.failed_at.should_not be_nil
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should re-schedule jobs after failing" do
|
123
|
+
@worker.run(@job)
|
124
|
+
@job.reload
|
125
|
+
@job.last_error.should =~ /did not work/
|
126
|
+
@job.last_error.should =~ /sample_jobs.rb:8:in `perform'/
|
127
|
+
@job.attempts.should == 1
|
128
|
+
@job.run_at.should > Delayed::Job.db_time_now - 10.minutes
|
129
|
+
@job.run_at.should < Delayed::Job.db_time_now + 10.minutes
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
context "reschedule" do
|
134
|
+
before do
|
135
|
+
@job = Delayed::Job.create :payload_object => SimpleJob.new
|
136
|
+
end
|
137
|
+
|
138
|
+
share_examples_for "any failure more than Worker.max_attempts times" do
|
139
|
+
context "when the job's payload has an #on_permanent_failure hook" do
|
140
|
+
before do
|
141
|
+
@job = Delayed::Job.create :payload_object => OnPermanentFailureJob.new
|
142
|
+
@job.payload_object.should respond_to :on_permanent_failure
|
143
|
+
end
|
144
|
+
|
145
|
+
it "should run that hook" do
|
146
|
+
@job.payload_object.should_receive :on_permanent_failure
|
147
|
+
Delayed::Worker.max_attempts.times { @worker.reschedule(@job) }
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
context "when the job's payload has no #on_permanent_failure hook" do
|
152
|
+
# It's a little tricky to test this in a straightforward way,
|
153
|
+
# because putting a should_not_receive expectation on
|
154
|
+
# @job.payload_object.on_permanent_failure makes that object
|
155
|
+
# incorrectly return true to
|
156
|
+
# payload_object.respond_to? :on_permanent_failure, which is what
|
157
|
+
# reschedule uses to decide whether to call on_permanent_failure.
|
158
|
+
# So instead, we just make sure that the payload_object as it
|
159
|
+
# already stands doesn't respond_to? on_permanent_failure, then
|
160
|
+
# shove it through the iterated reschedule loop and make sure we
|
161
|
+
# don't get a NoMethodError (caused by calling that nonexistent
|
162
|
+
# on_permanent_failure method).
|
163
|
+
|
164
|
+
before do
|
165
|
+
@job.payload_object.should_not respond_to(:on_permanent_failure)
|
166
|
+
end
|
167
|
+
|
168
|
+
it "should not try to run that hook" do
|
169
|
+
lambda do
|
170
|
+
Delayed::Worker.max_attempts.times { @worker.reschedule(@job) }
|
171
|
+
end.should_not raise_exception(NoMethodError)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
context "and we want to destroy jobs" do
|
177
|
+
before do
|
178
|
+
Delayed::Worker.destroy_failed_jobs = true
|
179
|
+
end
|
180
|
+
|
181
|
+
it_should_behave_like "any failure more than Worker.max_attempts times"
|
182
|
+
|
183
|
+
it "should be destroyed if it failed more than Worker.max_attempts times" do
|
184
|
+
@job.should_receive(:destroy)
|
185
|
+
Delayed::Worker.max_attempts.times { @worker.reschedule(@job) }
|
186
|
+
end
|
187
|
+
|
188
|
+
it "should not be destroyed if failed fewer than Worker.max_attempts times" do
|
189
|
+
@job.should_not_receive(:destroy)
|
190
|
+
(Delayed::Worker.max_attempts - 1).times { @worker.reschedule(@job) }
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
context "and we don't want to destroy jobs" do
|
195
|
+
before do
|
196
|
+
Delayed::Worker.destroy_failed_jobs = false
|
197
|
+
end
|
198
|
+
|
199
|
+
it_should_behave_like "any failure more than Worker.max_attempts times"
|
200
|
+
|
201
|
+
it "should be failed if it failed more than Worker.max_attempts times" do
|
202
|
+
@job.reload.failed_at.should == nil
|
203
|
+
Delayed::Worker.max_attempts.times { @worker.reschedule(@job) }
|
204
|
+
@job.reload.failed_at.should_not == nil
|
205
|
+
end
|
206
|
+
|
207
|
+
it "should not be failed if it failed fewer than Worker.max_attempts times" do
|
208
|
+
(Delayed::Worker.max_attempts - 1).times { @worker.reschedule(@job) }
|
209
|
+
@job.reload.failed_at.should == nil
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
end
|
data/tasks/jobs.rake
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'delayed', 'tasks'))
|
metadata
ADDED
@@ -0,0 +1,256 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: opsb-delayed_job
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 9
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 2
|
8
|
+
- 0
|
9
|
+
- 3
|
10
|
+
version: 2.0.3
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Brandon Keepers
|
14
|
+
- "Tobias L\xC3\xBCtke"
|
15
|
+
autorequire:
|
16
|
+
bindir: bin
|
17
|
+
cert_chain: []
|
18
|
+
|
19
|
+
date: 2010-04-16 00:00:00 +01:00
|
20
|
+
default_executable:
|
21
|
+
dependencies:
|
22
|
+
- !ruby/object:Gem::Dependency
|
23
|
+
name: daemons
|
24
|
+
prerelease: false
|
25
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ">="
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
hash: 3
|
31
|
+
segments:
|
32
|
+
- 0
|
33
|
+
version: "0"
|
34
|
+
type: :runtime
|
35
|
+
version_requirements: *id001
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rspec
|
38
|
+
prerelease: false
|
39
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
hash: 3
|
45
|
+
segments:
|
46
|
+
- 0
|
47
|
+
version: "0"
|
48
|
+
type: :development
|
49
|
+
version_requirements: *id002
|
50
|
+
- !ruby/object:Gem::Dependency
|
51
|
+
name: sqlite3-ruby
|
52
|
+
prerelease: false
|
53
|
+
requirement: &id003 !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
|
+
type: :development
|
63
|
+
version_requirements: *id003
|
64
|
+
- !ruby/object:Gem::Dependency
|
65
|
+
name: mongo_mapper
|
66
|
+
prerelease: false
|
67
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
68
|
+
none: false
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
hash: 3
|
73
|
+
segments:
|
74
|
+
- 0
|
75
|
+
version: "0"
|
76
|
+
type: :development
|
77
|
+
version_requirements: *id004
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: dm-core
|
80
|
+
prerelease: false
|
81
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
82
|
+
none: false
|
83
|
+
requirements:
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
hash: 3
|
87
|
+
segments:
|
88
|
+
- 0
|
89
|
+
version: "0"
|
90
|
+
type: :development
|
91
|
+
version_requirements: *id005
|
92
|
+
- !ruby/object:Gem::Dependency
|
93
|
+
name: dm-observer
|
94
|
+
prerelease: false
|
95
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
96
|
+
none: false
|
97
|
+
requirements:
|
98
|
+
- - ">="
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
hash: 3
|
101
|
+
segments:
|
102
|
+
- 0
|
103
|
+
version: "0"
|
104
|
+
type: :development
|
105
|
+
version_requirements: *id006
|
106
|
+
- !ruby/object:Gem::Dependency
|
107
|
+
name: dm-aggregates
|
108
|
+
prerelease: false
|
109
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
110
|
+
none: false
|
111
|
+
requirements:
|
112
|
+
- - ">="
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
hash: 3
|
115
|
+
segments:
|
116
|
+
- 0
|
117
|
+
version: "0"
|
118
|
+
type: :development
|
119
|
+
version_requirements: *id007
|
120
|
+
- !ruby/object:Gem::Dependency
|
121
|
+
name: dm-validations
|
122
|
+
prerelease: false
|
123
|
+
requirement: &id008 !ruby/object:Gem::Requirement
|
124
|
+
none: false
|
125
|
+
requirements:
|
126
|
+
- - ">="
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
hash: 3
|
129
|
+
segments:
|
130
|
+
- 0
|
131
|
+
version: "0"
|
132
|
+
type: :development
|
133
|
+
version_requirements: *id008
|
134
|
+
- !ruby/object:Gem::Dependency
|
135
|
+
name: do_sqlite3
|
136
|
+
prerelease: false
|
137
|
+
requirement: &id009 !ruby/object:Gem::Requirement
|
138
|
+
none: false
|
139
|
+
requirements:
|
140
|
+
- - ">="
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
hash: 3
|
143
|
+
segments:
|
144
|
+
- 0
|
145
|
+
version: "0"
|
146
|
+
type: :development
|
147
|
+
version_requirements: *id009
|
148
|
+
- !ruby/object:Gem::Dependency
|
149
|
+
name: database_cleaner
|
150
|
+
prerelease: false
|
151
|
+
requirement: &id010 !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
|
+
type: :development
|
161
|
+
version_requirements: *id010
|
162
|
+
description: |-
|
163
|
+
Delayed_job (or DJ) encapsulates the common pattern of asynchronously executing longer tasks in the background. It is a direct extraction from Shopify where the job table is responsible for a multitude of core tasks.
|
164
|
+
|
165
|
+
This gem is collectiveidea's fork (http://github.com/collectiveidea/delayed_job).
|
166
|
+
email: tobi@leetsoft.com
|
167
|
+
executables: []
|
168
|
+
|
169
|
+
extensions: []
|
170
|
+
|
171
|
+
extra_rdoc_files:
|
172
|
+
- README.textile
|
173
|
+
files:
|
174
|
+
- .gitignore
|
175
|
+
- MIT-LICENSE
|
176
|
+
- README.textile
|
177
|
+
- Rakefile
|
178
|
+
- VERSION
|
179
|
+
- benchmarks.rb
|
180
|
+
- contrib/delayed_job.monitrc
|
181
|
+
- contrib/delayed_job_multiple.monitrc
|
182
|
+
- delayed_job.gemspec
|
183
|
+
- generators/delayed_job/delayed_job_generator.rb
|
184
|
+
- generators/delayed_job/templates/migration.rb
|
185
|
+
- generators/delayed_job/templates/script
|
186
|
+
- init.rb
|
187
|
+
- lib/delayed/backend/active_record.rb
|
188
|
+
- lib/delayed/backend/base.rb
|
189
|
+
- lib/delayed/backend/data_mapper.rb
|
190
|
+
- lib/delayed/backend/mongo_mapper.rb
|
191
|
+
- lib/delayed/command.rb
|
192
|
+
- lib/delayed/message_sending.rb
|
193
|
+
- lib/delayed/performable_method.rb
|
194
|
+
- lib/delayed/railtie.rb
|
195
|
+
- lib/delayed/recipes.rb
|
196
|
+
- lib/delayed/tasks.rb
|
197
|
+
- lib/delayed/worker.rb
|
198
|
+
- lib/delayed_job.rb
|
199
|
+
- rails/init.rb
|
200
|
+
- recipes/delayed_job.rb
|
201
|
+
- spec/backend/active_record_job_spec.rb
|
202
|
+
- spec/backend/data_mapper_job_spec.rb
|
203
|
+
- spec/backend/mongo_mapper_job_spec.rb
|
204
|
+
- spec/backend/shared_backend_spec.rb
|
205
|
+
- spec/delayed_method_spec.rb
|
206
|
+
- spec/performable_method_spec.rb
|
207
|
+
- spec/sample_jobs.rb
|
208
|
+
- spec/setup/active_record.rb
|
209
|
+
- spec/setup/data_mapper.rb
|
210
|
+
- spec/setup/mongo_mapper.rb
|
211
|
+
- spec/spec_helper.rb
|
212
|
+
- spec/story_spec.rb
|
213
|
+
- spec/worker_spec.rb
|
214
|
+
- tasks/jobs.rake
|
215
|
+
has_rdoc: true
|
216
|
+
homepage: http://github.com/collectiveidea/delayed_job
|
217
|
+
licenses: []
|
218
|
+
|
219
|
+
post_install_message:
|
220
|
+
rdoc_options:
|
221
|
+
- --main
|
222
|
+
- README.textile
|
223
|
+
- --inline-source
|
224
|
+
- --line-numbers
|
225
|
+
require_paths:
|
226
|
+
- lib
|
227
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
228
|
+
none: false
|
229
|
+
requirements:
|
230
|
+
- - ">="
|
231
|
+
- !ruby/object:Gem::Version
|
232
|
+
hash: 3
|
233
|
+
segments:
|
234
|
+
- 0
|
235
|
+
version: "0"
|
236
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
237
|
+
none: false
|
238
|
+
requirements:
|
239
|
+
- - ">="
|
240
|
+
- !ruby/object:Gem::Version
|
241
|
+
hash: 3
|
242
|
+
segments:
|
243
|
+
- 0
|
244
|
+
version: "0"
|
245
|
+
requirements: []
|
246
|
+
|
247
|
+
rubyforge_project:
|
248
|
+
rubygems_version: 1.3.7
|
249
|
+
signing_key:
|
250
|
+
specification_version: 3
|
251
|
+
summary: Database-backed asynchronous priority queue system -- Extracted from Shopify
|
252
|
+
test_files:
|
253
|
+
- spec/delayed_method_spec.rb
|
254
|
+
- spec/performable_method_spec.rb
|
255
|
+
- spec/story_spec.rb
|
256
|
+
- spec/worker_spec.rb
|