resque-loner 1.0.1 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,332 @@
1
+ require 'test_helper'
2
+
3
+ context "Resque::Worker" do
4
+ setup do
5
+ Resque.redis.flushall
6
+
7
+ Resque.before_first_fork = nil
8
+ Resque.before_fork = nil
9
+ Resque.after_fork = nil
10
+
11
+ @worker = Resque::Worker.new(:jobs)
12
+ Resque::Job.create(:jobs, SomeJob, 20, '/tmp')
13
+ end
14
+
15
+ test "can fail jobs" do
16
+ Resque::Job.create(:jobs, BadJob)
17
+ @worker.work(0)
18
+ assert_equal 1, Resque::Failure.count
19
+ end
20
+
21
+ test "failed jobs report exception and message" do
22
+ Resque::Job.create(:jobs, BadJobWithSyntaxError)
23
+ @worker.work(0)
24
+ assert_equal('SyntaxError', Resque::Failure.all['exception'])
25
+ assert_equal('Extra Bad job!', Resque::Failure.all['error'])
26
+ end
27
+
28
+ test "does not allow exceptions from failure backend to escape" do
29
+ job = Resque::Job.new(:jobs, {})
30
+ with_failure_backend BadFailureBackend do
31
+ @worker.perform job
32
+ end
33
+ end
34
+
35
+ test "fails uncompleted jobs on exit" do
36
+ job = Resque::Job.new(:jobs, [GoodJob, "blah"])
37
+ @worker.working_on(job)
38
+ @worker.unregister_worker
39
+ assert_equal 1, Resque::Failure.count
40
+ end
41
+
42
+ test "can peek at failed jobs" do
43
+ 10.times { Resque::Job.create(:jobs, BadJob) }
44
+ @worker.work(0)
45
+ assert_equal 10, Resque::Failure.count
46
+
47
+ assert_equal 10, Resque::Failure.all(0, 20).size
48
+ end
49
+
50
+ test "can clear failed jobs" do
51
+ Resque::Job.create(:jobs, BadJob)
52
+ @worker.work(0)
53
+ assert_equal 1, Resque::Failure.count
54
+ Resque::Failure.clear
55
+ assert_equal 0, Resque::Failure.count
56
+ end
57
+
58
+ test "catches exceptional jobs" do
59
+ Resque::Job.create(:jobs, BadJob)
60
+ Resque::Job.create(:jobs, BadJob)
61
+ @worker.process
62
+ @worker.process
63
+ @worker.process
64
+ assert_equal 2, Resque::Failure.count
65
+ end
66
+
67
+ test "strips whitespace from queue names" do
68
+ queues = "critical, high, low".split(',')
69
+ worker = Resque::Worker.new(*queues)
70
+ assert_equal %w( critical high low ), worker.queues
71
+ end
72
+
73
+ test "can work on multiple queues" do
74
+ Resque::Job.create(:high, GoodJob)
75
+ Resque::Job.create(:critical, GoodJob)
76
+
77
+ worker = Resque::Worker.new(:critical, :high)
78
+
79
+ worker.process
80
+ assert_equal 1, Resque.size(:high)
81
+ assert_equal 0, Resque.size(:critical)
82
+
83
+ worker.process
84
+ assert_equal 0, Resque.size(:high)
85
+ end
86
+
87
+ test "can work on all queues" do
88
+ Resque::Job.create(:high, GoodJob)
89
+ Resque::Job.create(:critical, GoodJob)
90
+ Resque::Job.create(:blahblah, GoodJob)
91
+
92
+ worker = Resque::Worker.new("*")
93
+
94
+ worker.work(0)
95
+ assert_equal 0, Resque.size(:high)
96
+ assert_equal 0, Resque.size(:critical)
97
+ assert_equal 0, Resque.size(:blahblah)
98
+ end
99
+
100
+ test "processes * queues in alphabetical order" do
101
+ Resque::Job.create(:high, GoodJob)
102
+ Resque::Job.create(:critical, GoodJob)
103
+ Resque::Job.create(:blahblah, GoodJob)
104
+
105
+ worker = Resque::Worker.new("*")
106
+ processed_queues = []
107
+
108
+ worker.work(0) do |job|
109
+ processed_queues << job.queue
110
+ end
111
+
112
+ assert_equal %w( jobs high critical blahblah ).sort, processed_queues
113
+ end
114
+
115
+ test "has a unique id" do
116
+ assert_equal "#{`hostname`.chomp}:#{$$}:jobs", @worker.to_s
117
+ end
118
+
119
+ test "complains if no queues are given" do
120
+ assert_raise Resque::NoQueueError do
121
+ Resque::Worker.new
122
+ end
123
+ end
124
+
125
+ test "fails if a job class has no `perform` method" do
126
+ worker = Resque::Worker.new(:perform_less)
127
+ Resque::Job.create(:perform_less, Object)
128
+
129
+ assert_equal 0, Resque::Failure.count
130
+ worker.work(0)
131
+ assert_equal 1, Resque::Failure.count
132
+ end
133
+
134
+ test "inserts itself into the 'workers' list on startup" do
135
+ @worker.work(0) do
136
+ assert_equal @worker, Resque.workers[0]
137
+ end
138
+ end
139
+
140
+ test "removes itself from the 'workers' list on shutdown" do
141
+ @worker.work(0) do
142
+ assert_equal @worker, Resque.workers[0]
143
+ end
144
+
145
+ assert_equal [], Resque.workers
146
+ end
147
+
148
+ test "removes worker with stringified id" do
149
+ @worker.work(0) do
150
+ worker_id = Resque.workers[0].to_s
151
+ Resque.remove_worker(worker_id)
152
+ assert_equal [], Resque.workers
153
+ end
154
+ end
155
+
156
+ test "records what it is working on" do
157
+ @worker.work(0) do
158
+ task = @worker.job
159
+ assert_equal({"args"=>[20, "/tmp"], "class"=>"SomeJob"}, task['payload'])
160
+ assert task['run_at']
161
+ assert_equal 'jobs', task['queue']
162
+ end
163
+ end
164
+
165
+ test "clears its status when not working on anything" do
166
+ @worker.work(0)
167
+ assert_equal Hash.new, @worker.job
168
+ end
169
+
170
+ test "knows when it is working" do
171
+ @worker.work(0) do
172
+ assert @worker.working?
173
+ end
174
+ end
175
+
176
+ test "knows when it is idle" do
177
+ @worker.work(0)
178
+ assert @worker.idle?
179
+ end
180
+
181
+ test "knows who is working" do
182
+ @worker.work(0) do
183
+ assert_equal [@worker], Resque.working
184
+ end
185
+ end
186
+
187
+ test "keeps track of how many jobs it has processed" do
188
+ Resque::Job.create(:jobs, BadJob)
189
+ Resque::Job.create(:jobs, BadJob)
190
+
191
+ 3.times do
192
+ job = @worker.reserve
193
+ @worker.process job
194
+ end
195
+ assert_equal 3, @worker.processed
196
+ end
197
+
198
+ test "keeps track of how many failures it has seen" do
199
+ Resque::Job.create(:jobs, BadJob)
200
+ Resque::Job.create(:jobs, BadJob)
201
+
202
+ 3.times do
203
+ job = @worker.reserve
204
+ @worker.process job
205
+ end
206
+ assert_equal 2, @worker.failed
207
+ end
208
+
209
+ test "stats are erased when the worker goes away" do
210
+ @worker.work(0)
211
+ assert_equal 0, @worker.processed
212
+ assert_equal 0, @worker.failed
213
+ end
214
+
215
+ test "knows when it started" do
216
+ time = Time.now
217
+ @worker.work(0) do
218
+ assert_equal time.to_s, @worker.started.to_s
219
+ end
220
+ end
221
+
222
+ test "knows whether it exists or not" do
223
+ @worker.work(0) do
224
+ assert Resque::Worker.exists?(@worker)
225
+ assert !Resque::Worker.exists?('blah-blah')
226
+ end
227
+ end
228
+
229
+ test "sets $0 while working" do
230
+ @worker.work(0) do
231
+ ver = Resque::Version
232
+ assert_equal "resque-#{ver}: Processing jobs since #{Time.now.to_i}", $0
233
+ end
234
+ end
235
+
236
+ test "can be found" do
237
+ @worker.work(0) do
238
+ found = Resque::Worker.find(@worker.to_s)
239
+ assert_equal @worker.to_s, found.to_s
240
+ assert found.working?
241
+ assert_equal @worker.job, found.job
242
+ end
243
+ end
244
+
245
+ test "doesn't find fakes" do
246
+ @worker.work(0) do
247
+ found = Resque::Worker.find('blah-blah')
248
+ assert_equal nil, found
249
+ end
250
+ end
251
+
252
+ test "cleans up dead worker info on start (crash recovery)" do
253
+ # first we fake out two dead workers
254
+ workerA = Resque::Worker.new(:jobs)
255
+ workerA.instance_variable_set(:@to_s, "#{`hostname`.chomp}:1:jobs")
256
+ workerA.register_worker
257
+
258
+ workerB = Resque::Worker.new(:high, :low)
259
+ workerB.instance_variable_set(:@to_s, "#{`hostname`.chomp}:2:high,low")
260
+ workerB.register_worker
261
+
262
+ assert_equal 2, Resque.workers.size
263
+
264
+ # then we prune them
265
+ @worker.work(0) do
266
+ assert_equal 1, Resque.workers.size
267
+ end
268
+ end
269
+
270
+ test "Processed jobs count" do
271
+ @worker.work(0)
272
+ assert_equal 1, Resque.info[:processed]
273
+ end
274
+
275
+ test "Will call a before_first_fork hook only once" do
276
+ Resque.redis.flushall
277
+ $BEFORE_FORK_CALLED = 0
278
+ Resque.before_first_fork = Proc.new { $BEFORE_FORK_CALLED += 1 }
279
+ workerA = Resque::Worker.new(:jobs)
280
+ Resque::Job.create(:jobs, SomeJob, 20, '/tmp')
281
+
282
+ assert_equal 0, $BEFORE_FORK_CALLED
283
+
284
+ workerA.work(0)
285
+ assert_equal 1, $BEFORE_FORK_CALLED
286
+
287
+ # TODO: Verify it's only run once. Not easy.
288
+ # workerA.work(0)
289
+ # assert_equal 1, $BEFORE_FORK_CALLED
290
+ end
291
+
292
+ test "Will call a before_fork hook before forking" do
293
+ Resque.redis.flushall
294
+ $BEFORE_FORK_CALLED = false
295
+ Resque.before_fork = Proc.new { $BEFORE_FORK_CALLED = true }
296
+ workerA = Resque::Worker.new(:jobs)
297
+
298
+ assert !$BEFORE_FORK_CALLED
299
+ Resque::Job.create(:jobs, SomeJob, 20, '/tmp')
300
+ workerA.work(0)
301
+ assert $BEFORE_FORK_CALLED
302
+ end
303
+
304
+ test "very verbose works in the afternoon" do
305
+ require 'time'
306
+ $last_puts = ""
307
+ $fake_time = Time.parse("15:44:33 2011-03-02")
308
+ singleton = class << @worker; self end
309
+ singleton.send :define_method, :puts, lambda { |thing| $last_puts = thing }
310
+
311
+ @worker.very_verbose = true
312
+ @worker.log("some log text")
313
+
314
+ assert_match /\*\* \[15:44:33 2011-03-02\] \d+: some log text/, $last_puts
315
+ end
316
+
317
+ test "Will call an after_fork hook after forking" do
318
+ Resque.redis.flushall
319
+ $AFTER_FORK_CALLED = false
320
+ Resque.after_fork = Proc.new { $AFTER_FORK_CALLED = true }
321
+ workerA = Resque::Worker.new(:jobs)
322
+
323
+ assert !$AFTER_FORK_CALLED
324
+ Resque::Job.create(:jobs, SomeJob, 20, '/tmp')
325
+ workerA.work(0)
326
+ assert $AFTER_FORK_CALLED
327
+ end
328
+
329
+ test "returns PID of running process" do
330
+ assert_equal @worker.to_s.split(":")[1].to_i, @worker.pid
331
+ end
332
+ end
metadata CHANGED
@@ -1,131 +1,161 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: resque-loner
3
- version: !ruby/object:Gem::Version
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.2.0
4
5
  prerelease:
5
- version: 1.0.1
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - Jannis Hermanns
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
-
13
- date: 2011-07-15 00:00:00 +02:00
14
- default_executable:
15
- dependencies:
16
- - !ruby/object:Gem::Dependency
12
+ date: 2012-01-11 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
17
15
  name: resque
18
- prerelease: false
19
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &70253469641240 !ruby/object:Gem::Requirement
20
17
  none: false
21
- requirements:
18
+ requirements:
22
19
  - - ~>
23
- - !ruby/object:Gem::Version
24
- version: "1.0"
20
+ - !ruby/object:Gem::Version
21
+ version: '1.0'
25
22
  type: :runtime
26
- version_requirements: *id001
27
- - !ruby/object:Gem::Dependency
28
- name: bundler
29
23
  prerelease: false
30
- requirement: &id002 !ruby/object:Gem::Requirement
24
+ version_requirements: *70253469641240
25
+ - !ruby/object:Gem::Dependency
26
+ name: rake
27
+ requirement: &70253469640360 !ruby/object:Gem::Requirement
31
28
  none: false
32
- requirements:
29
+ requirements:
30
+ - - ! '>'
31
+ - !ruby/object:Gem::Version
32
+ version: 0.8.7
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *70253469640360
36
+ - !ruby/object:Gem::Dependency
37
+ name: rack-test
38
+ requirement: &70253469639860 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
33
41
  - - ~>
34
- - !ruby/object:Gem::Version
35
- version: 1.0.0
42
+ - !ruby/object:Gem::Version
43
+ version: 0.5.7
36
44
  type: :development
37
- version_requirements: *id002
38
- - !ruby/object:Gem::Dependency
39
- name: rake
40
45
  prerelease: false
41
- requirement: &id003 !ruby/object:Gem::Requirement
46
+ version_requirements: *70253469639860
47
+ - !ruby/object:Gem::Dependency
48
+ name: rspec
49
+ requirement: &70253469639420 !ruby/object:Gem::Requirement
42
50
  none: false
43
- requirements:
51
+ requirements:
44
52
  - - ~>
45
- - !ruby/object:Gem::Version
46
- version: 0.8.7
53
+ - !ruby/object:Gem::Version
54
+ version: 2.5.0
47
55
  type: :development
48
- version_requirements: *id003
49
- - !ruby/object:Gem::Dependency
50
- name: rack-test
51
56
  prerelease: false
52
- requirement: &id004 !ruby/object:Gem::Requirement
57
+ version_requirements: *70253469639420
58
+ - !ruby/object:Gem::Dependency
59
+ name: mock_redis
60
+ requirement: &70253469638940 !ruby/object:Gem::Requirement
53
61
  none: false
54
- requirements:
62
+ requirements:
55
63
  - - ~>
56
- - !ruby/object:Gem::Version
57
- version: 0.5.7
64
+ - !ruby/object:Gem::Version
65
+ version: 0.2.0
58
66
  type: :development
59
- version_requirements: *id004
60
- - !ruby/object:Gem::Dependency
61
- name: rspec
62
67
  prerelease: false
63
- requirement: &id005 !ruby/object:Gem::Requirement
68
+ version_requirements: *70253469638940
69
+ - !ruby/object:Gem::Dependency
70
+ name: yajl-ruby
71
+ requirement: &70253469637680 !ruby/object:Gem::Requirement
64
72
  none: false
65
- requirements:
73
+ requirements:
66
74
  - - ~>
67
- - !ruby/object:Gem::Version
68
- version: 2.5.0
75
+ - !ruby/object:Gem::Version
76
+ version: 0.8.2
69
77
  type: :development
70
- version_requirements: *id005
71
- description: |
72
- Makes sure that for special jobs, there can be only one job with the same workload in one queue.
73
-
74
- Example:
75
- class CacheSweeper
76
-
77
- include Resque::Plugins::UniqueJob
78
-
79
- @queue = :cache_sweeps
80
-
81
- def self.perform(article_id)
82
- # Cache Me If You Can...
83
- end
84
- end
85
-
86
- email:
78
+ prerelease: false
79
+ version_requirements: *70253469637680
80
+ description: ! "Makes sure that for special jobs, there can be only one job with the
81
+ same workload in one queue.\n\nExample:\n class CacheSweeper \n\n include
82
+ Resque::Plugins::UniqueJob\n\n @queue = :cache_sweeps\n\n def self.perform(article_id)\n
83
+ \ # Cache Me If You Can...\n end\n end\n"
84
+ email:
87
85
  - jannis@moviepilot.com
88
86
  executables: []
89
-
90
87
  extensions: []
91
-
92
88
  extra_rdoc_files: []
93
-
94
- files:
89
+ files:
90
+ - .gitignore
91
+ - CHANGELOG.markdown
92
+ - Gemfile
93
+ - LICENSE
94
+ - README.markdown
95
+ - Rakefile
96
+ - init.rb
95
97
  - lib/resque-ext/job.rb
96
98
  - lib/resque-ext/resque.rb
99
+ - lib/resque-loner.rb
97
100
  - lib/resque-loner/helpers.rb
98
101
  - lib/resque-loner/unique_job.rb
99
102
  - lib/resque-loner/version.rb
100
- - lib/resque-loner.rb
101
- - README.markdown
102
- has_rdoc: true
103
+ - rails/init.rb
104
+ - resque-loner.gemspec
105
+ - spec/loner_spec.rb
106
+ - spec/redis-test.conf
107
+ - spec/spec_helper.rb
108
+ - tasks/redis.rake
109
+ - tasks/resque.rake
110
+ - test/hoptoad_test.rb
111
+ - test/job_hooks_test.rb
112
+ - test/job_plugins_test.rb
113
+ - test/plugin_test.rb
114
+ - test/redis-test.conf
115
+ - test/resque-web_test.rb
116
+ - test/resque_test.rb
117
+ - test/test_helper.rb
118
+ - test/worker_test.rb
103
119
  homepage: http://github.com/jayniz/resque-loner
104
120
  licenses: []
105
-
106
121
  post_install_message:
107
122
  rdoc_options: []
108
-
109
- require_paths:
123
+ require_paths:
110
124
  - lib
111
- required_ruby_version: !ruby/object:Gem::Requirement
125
+ required_ruby_version: !ruby/object:Gem::Requirement
112
126
  none: false
113
- requirements:
114
- - - ">="
115
- - !ruby/object:Gem::Version
116
- version: "0"
117
- required_rubygems_version: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ! '>='
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
131
+ segments:
132
+ - 0
133
+ hash: -1484612599383235798
134
+ required_rubygems_version: !ruby/object:Gem::Requirement
118
135
  none: false
119
- requirements:
120
- - - ">="
121
- - !ruby/object:Gem::Version
122
- version: "0"
136
+ requirements:
137
+ - - ! '>='
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
140
+ segments:
141
+ - 0
142
+ hash: -1484612599383235798
123
143
  requirements: []
124
-
125
144
  rubyforge_project: resque-loner
126
- rubygems_version: 1.5.2
145
+ rubygems_version: 1.8.10
127
146
  signing_key:
128
147
  specification_version: 3
129
148
  summary: Adds unique jobs to resque
130
- test_files: []
131
-
149
+ test_files:
150
+ - spec/loner_spec.rb
151
+ - spec/redis-test.conf
152
+ - spec/spec_helper.rb
153
+ - test/hoptoad_test.rb
154
+ - test/job_hooks_test.rb
155
+ - test/job_plugins_test.rb
156
+ - test/plugin_test.rb
157
+ - test/redis-test.conf
158
+ - test/resque-web_test.rb
159
+ - test/resque_test.rb
160
+ - test/test_helper.rb
161
+ - test/worker_test.rb