delayed_job 2.1.0.pre → 2.1.0.pre2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,273 +0,0 @@
1
- class NamedJob < Struct.new(:perform)
2
- def display_name
3
- 'named_job'
4
- end
5
- end
6
-
7
- shared_examples_for 'a backend' do
8
- def create_job(opts = {})
9
- @backend.create(opts.merge(:payload_object => SimpleJob.new))
10
- end
11
-
12
- before do
13
- Delayed::Worker.max_priority = nil
14
- Delayed::Worker.min_priority = nil
15
- SimpleJob.runs = 0
16
- end
17
-
18
- it "should set run_at automatically if not set" do
19
- @backend.create(:payload_object => ErrorJob.new ).run_at.should_not be_nil
20
- end
21
-
22
- it "should not set run_at automatically if already set" do
23
- later = @backend.db_time_now + 5.minutes
24
- @backend.create(:payload_object => ErrorJob.new, :run_at => later).run_at.should be_close(later, 1)
25
- end
26
-
27
- it "should raise ArgumentError when handler doesn't respond_to :perform" do
28
- lambda { @backend.enqueue(Object.new) }.should raise_error(ArgumentError)
29
- end
30
-
31
- it "should increase count after enqueuing items" do
32
- @backend.enqueue SimpleJob.new
33
- @backend.count.should == 1
34
- end
35
-
36
- it "should be able to set priority when enqueuing items" do
37
- @job = @backend.enqueue SimpleJob.new, 5
38
- @job.priority.should == 5
39
- end
40
-
41
- it "should be able to set run_at when enqueuing items" do
42
- later = @backend.db_time_now + 5.minutes
43
- @job = @backend.enqueue SimpleJob.new, 5, later
44
- @job.run_at.should be_close(later, 1)
45
- end
46
-
47
- it "should work with jobs in modules" do
48
- M::ModuleJob.runs = 0
49
- job = @backend.enqueue M::ModuleJob.new
50
- lambda { job.invoke_job }.should change { M::ModuleJob.runs }.from(0).to(1)
51
- end
52
-
53
- describe "payload_object" do
54
- it "should raise a DeserializationError when the job class is totally unknown" do
55
- job = @backend.new :handler => "--- !ruby/object:JobThatDoesNotExist {}"
56
- lambda { job.payload_object }.should raise_error(Delayed::Backend::DeserializationError)
57
- end
58
-
59
- it "should raise a DeserializationError when the job struct is totally unknown" do
60
- job = @backend.new :handler => "--- !ruby/struct:StructThatDoesNotExist {}"
61
- lambda { job.payload_object }.should raise_error(Delayed::Backend::DeserializationError)
62
- end
63
-
64
- it "should autoload classes that are unknown at runtime" do
65
- job = @backend.new :handler => "--- !ruby/object:Autoloaded::Clazz {}"
66
- lambda { job.payload_object }.should_not raise_error(Delayed::Backend::DeserializationError)
67
- end
68
-
69
- it "should autoload structs that are unknown at runtime" do
70
- job = @backend.new :handler => "--- !ruby/struct:Autoloaded::Struct {}"
71
- lambda { job.payload_object }.should_not raise_error(Delayed::Backend::DeserializationError)
72
- end
73
- end
74
-
75
- describe "find_available" do
76
- it "should not find failed jobs" do
77
- @job = create_job :attempts => 50, :failed_at => @backend.db_time_now
78
- @backend.find_available('worker', 5, 1.second).should_not include(@job)
79
- end
80
-
81
- it "should not find jobs scheduled for the future" do
82
- @job = create_job :run_at => (@backend.db_time_now + 1.minute)
83
- @backend.find_available('worker', 5, 4.hours).should_not include(@job)
84
- end
85
-
86
- it "should not find jobs locked by another worker" do
87
- @job = create_job(:locked_by => 'other_worker', :locked_at => @backend.db_time_now - 1.minute)
88
- @backend.find_available('worker', 5, 4.hours).should_not include(@job)
89
- end
90
-
91
- it "should find open jobs" do
92
- @job = create_job
93
- @backend.find_available('worker', 5, 4.hours).should include(@job)
94
- end
95
-
96
- it "should find expired jobs" do
97
- @job = create_job(:locked_by => 'worker', :locked_at => @backend.db_time_now - 2.minutes)
98
- @backend.find_available('worker', 5, 1.minute).should include(@job)
99
- end
100
-
101
- it "should find own jobs" do
102
- @job = create_job(:locked_by => 'worker', :locked_at => (@backend.db_time_now - 1.minutes))
103
- @backend.find_available('worker', 5, 4.hours).should include(@job)
104
- end
105
-
106
- it "should find only the right amount of jobs" do
107
- 10.times { create_job }
108
- @backend.find_available('worker', 7, 4.hours).should have(7).jobs
109
- end
110
- end
111
-
112
- context "when another worker is already performing an task, it" do
113
-
114
- before :each do
115
- @job = @backend.create :payload_object => SimpleJob.new, :locked_by => 'worker1', :locked_at => @backend.db_time_now - 5.minutes
116
- end
117
-
118
- it "should not allow a second worker to get exclusive access" do
119
- @job.lock_exclusively!(4.hours, 'worker2').should == false
120
- end
121
-
122
- it "should allow a second worker to get exclusive access if the timeout has passed" do
123
- @job.lock_exclusively!(1.minute, 'worker2').should == true
124
- end
125
-
126
- it "should be able to get access to the task if it was started more then max_age ago" do
127
- @job.locked_at = 5.hours.ago
128
- @job.save
129
-
130
- @job.lock_exclusively! 4.hours, 'worker2'
131
- @job.reload
132
- @job.locked_by.should == 'worker2'
133
- @job.locked_at.should > 1.minute.ago
134
- end
135
-
136
- it "should not be found by another worker" do
137
- @backend.find_available('worker2', 1, 6.minutes).length.should == 0
138
- end
139
-
140
- it "should be found by another worker if the time has expired" do
141
- @backend.find_available('worker2', 1, 4.minutes).length.should == 1
142
- end
143
-
144
- it "should be able to get exclusive access again when the worker name is the same" do
145
- @job.lock_exclusively!(5.minutes, 'worker1').should be_true
146
- @job.lock_exclusively!(5.minutes, 'worker1').should be_true
147
- @job.lock_exclusively!(5.minutes, 'worker1').should be_true
148
- end
149
- end
150
-
151
- context "when another worker has worked on a task since the job was found to be available, it" do
152
-
153
- before :each do
154
- @job = @backend.create :payload_object => SimpleJob.new
155
- @job_copy_for_worker_2 = @backend.find(@job.id)
156
- end
157
-
158
- it "should not allow a second worker to get exclusive access if already successfully processed by worker1" do
159
- @job.destroy
160
- @job_copy_for_worker_2.lock_exclusively!(4.hours, 'worker2').should == false
161
- end
162
-
163
- it "should not allow a second worker to get exclusive access if failed to be processed by worker1 and run_at time is now in future (due to backing off behaviour)" do
164
- @job.update_attributes(:attempts => 1, :run_at => 1.day.from_now)
165
- @job_copy_for_worker_2.lock_exclusively!(4.hours, 'worker2').should == false
166
- end
167
- end
168
-
169
- context "#name" do
170
- it "should be the class name of the job that was enqueued" do
171
- @backend.create(:payload_object => ErrorJob.new ).name.should == 'ErrorJob'
172
- end
173
-
174
- it "should be the method that will be called if its a performable method object" do
175
- job = @backend.new(:payload_object => NamedJob.new)
176
- job.name.should == 'named_job'
177
- end
178
-
179
- it "should be the instance method that will be called if its a performable method object" do
180
- @job = Story.create(:text => "...").delay.save
181
- @job.name.should == 'Story#save'
182
- end
183
- end
184
-
185
- context "worker prioritization" do
186
- before(:each) do
187
- Delayed::Worker.max_priority = nil
188
- Delayed::Worker.min_priority = nil
189
- end
190
-
191
- it "should fetch jobs ordered by priority" do
192
- 10.times { @backend.enqueue SimpleJob.new, rand(10) }
193
- jobs = @backend.find_available('worker', 10)
194
- jobs.size.should == 10
195
- jobs.each_cons(2) do |a, b|
196
- a.priority.should <= b.priority
197
- end
198
- end
199
-
200
- it "should only find jobs greater than or equal to min priority" do
201
- min = 5
202
- Delayed::Worker.min_priority = min
203
- 10.times {|i| @backend.enqueue SimpleJob.new, i }
204
- jobs = @backend.find_available('worker', 10)
205
- jobs.each {|job| job.priority.should >= min}
206
- end
207
-
208
- it "should only find jobs less than or equal to max priority" do
209
- max = 5
210
- Delayed::Worker.max_priority = max
211
- 10.times {|i| @backend.enqueue SimpleJob.new, i }
212
- jobs = @backend.find_available('worker', 10)
213
- jobs.each {|job| job.priority.should <= max}
214
- end
215
- end
216
-
217
- context "clear_locks!" do
218
- before do
219
- @job = create_job(:locked_by => 'worker', :locked_at => @backend.db_time_now)
220
- end
221
-
222
- it "should clear locks for the given worker" do
223
- @backend.clear_locks!('worker')
224
- @backend.find_available('worker2', 5, 1.minute).should include(@job)
225
- end
226
-
227
- it "should not clear locks for other workers" do
228
- @backend.clear_locks!('worker1')
229
- @backend.find_available('worker1', 5, 1.minute).should_not include(@job)
230
- end
231
- end
232
-
233
- context "unlock" do
234
- before do
235
- @job = create_job(:locked_by => 'worker', :locked_at => @backend.db_time_now)
236
- end
237
-
238
- it "should clear locks" do
239
- @job.unlock
240
- @job.locked_by.should be_nil
241
- @job.locked_at.should be_nil
242
- end
243
- end
244
-
245
- context "large handler" do
246
- before do
247
- text = "Lorem ipsum dolor sit amet. " * 1000
248
- @job = @backend.enqueue Delayed::PerformableMethod.new(text, :length, {})
249
- end
250
-
251
- it "should have an id" do
252
- @job.id.should_not be_nil
253
- end
254
- end
255
-
256
- describe "yaml serialization" do
257
- it "should reload changed attributes" do
258
- job = @backend.enqueue SimpleJob.new
259
- yaml = job.to_yaml
260
- job.priority = 99
261
- job.save
262
- YAML.load(yaml).priority.should == 99
263
- end
264
-
265
- it "should ignore destroyed records" do
266
- job = @backend.enqueue SimpleJob.new
267
- yaml = job.to_yaml
268
- job.destroy
269
- lambda { YAML.load(yaml).should be_nil }.should_not raise_error
270
- end
271
- end
272
-
273
- end
@@ -1,33 +0,0 @@
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
@@ -1,7 +0,0 @@
1
- require 'couchrest'
2
- require 'delayed/backend/couch_rest'
3
-
4
- Delayed::Backend::CouchRest::Job.use_database CouchRest::Server.new.database!('delayed_job_spec')
5
-
6
- # try to perform a query to check that we can connect
7
- Delayed::Backend::CouchRest::Job.all
@@ -1,8 +0,0 @@
1
- require 'dm-core'
2
- require 'dm-validations'
3
-
4
- require 'delayed/backend/data_mapper'
5
-
6
- DataMapper.logger = Delayed::Worker.logger
7
- DataMapper.setup(:default, "sqlite3::memory:")
8
- DataMapper.auto_migrate!
@@ -1,17 +0,0 @@
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