resque 1.23.0 → 2.6.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 (70) hide show
  1. checksums.yaml +7 -0
  2. data/HISTORY.md +271 -0
  3. data/README.markdown +454 -484
  4. data/Rakefile +4 -17
  5. data/bin/resque-web +10 -22
  6. data/lib/resque/data_store.rb +335 -0
  7. data/lib/resque/errors.rb +15 -1
  8. data/lib/resque/failure/airbrake.rb +32 -4
  9. data/lib/resque/failure/base.rb +16 -7
  10. data/lib/resque/failure/multiple.rb +26 -8
  11. data/lib/resque/failure/redis.rb +92 -15
  12. data/lib/resque/failure/redis_multi_queue.rb +104 -0
  13. data/lib/resque/failure.rb +62 -32
  14. data/lib/resque/helpers.rb +11 -57
  15. data/lib/resque/job.rb +79 -12
  16. data/lib/resque/log_formatters/quiet_formatter.rb +7 -0
  17. data/lib/resque/log_formatters/verbose_formatter.rb +7 -0
  18. data/lib/resque/log_formatters/very_verbose_formatter.rb +8 -0
  19. data/lib/resque/logging.rb +18 -0
  20. data/lib/resque/plugin.rb +22 -10
  21. data/lib/resque/railtie.rb +10 -0
  22. data/lib/resque/server/public/jquery-3.6.0.min.js +2 -0
  23. data/lib/resque/server/public/jquery.relatize_date.js +4 -4
  24. data/lib/resque/server/public/main.js +3 -0
  25. data/lib/resque/server/public/ranger.js +16 -8
  26. data/lib/resque/server/public/style.css +13 -8
  27. data/lib/resque/server/views/error.erb +1 -1
  28. data/lib/resque/server/views/failed.erb +27 -59
  29. data/lib/resque/server/views/failed_job.erb +50 -0
  30. data/lib/resque/server/views/failed_queues_overview.erb +24 -0
  31. data/lib/resque/server/views/job_class.erb +8 -0
  32. data/lib/resque/server/views/key_sets.erb +2 -4
  33. data/lib/resque/server/views/key_string.erb +1 -1
  34. data/lib/resque/server/views/layout.erb +7 -6
  35. data/lib/resque/server/views/next_more.erb +22 -10
  36. data/lib/resque/server/views/processing.erb +2 -0
  37. data/lib/resque/server/views/queues.erb +22 -13
  38. data/lib/resque/server/views/stats.erb +5 -5
  39. data/lib/resque/server/views/workers.erb +4 -4
  40. data/lib/resque/server/views/working.erb +10 -11
  41. data/lib/resque/server.rb +51 -108
  42. data/lib/resque/server_helper.rb +185 -0
  43. data/lib/resque/stat.rb +19 -7
  44. data/lib/resque/tasks.rb +26 -25
  45. data/lib/resque/thread_signal.rb +24 -0
  46. data/lib/resque/vendor/utf8_util.rb +2 -8
  47. data/lib/resque/version.rb +1 -1
  48. data/lib/resque/web_runner.rb +374 -0
  49. data/lib/resque/worker.rb +487 -163
  50. data/lib/resque.rb +332 -52
  51. data/lib/tasks/redis.rake +11 -11
  52. metadata +169 -149
  53. data/lib/resque/failure/hoptoad.rb +0 -33
  54. data/lib/resque/failure/thoughtbot.rb +0 -33
  55. data/lib/resque/server/public/jquery-1.3.2.min.js +0 -19
  56. data/lib/resque/server/test_helper.rb +0 -19
  57. data/lib/resque/vendor/utf8_util/utf8_util_18.rb +0 -91
  58. data/lib/resque/vendor/utf8_util/utf8_util_19.rb +0 -5
  59. data/test/airbrake_test.rb +0 -27
  60. data/test/hoptoad_test.rb +0 -26
  61. data/test/job_hooks_test.rb +0 -464
  62. data/test/job_plugins_test.rb +0 -230
  63. data/test/plugin_test.rb +0 -116
  64. data/test/redis-test-cluster.conf +0 -115
  65. data/test/redis-test.conf +0 -115
  66. data/test/resque-web_test.rb +0 -59
  67. data/test/resque_failure_redis_test.rb +0 -19
  68. data/test/resque_test.rb +0 -278
  69. data/test/test_helper.rb +0 -178
  70. data/test/worker_test.rb +0 -657
data/test/resque_test.rb DELETED
@@ -1,278 +0,0 @@
1
- require 'test_helper'
2
-
3
- context "Resque" do
4
- setup do
5
- Resque.redis.flushall
6
-
7
- Resque.push(:people, { 'name' => 'chris' })
8
- Resque.push(:people, { 'name' => 'bob' })
9
- Resque.push(:people, { 'name' => 'mark' })
10
- @original_redis = Resque.redis
11
- end
12
-
13
- teardown do
14
- Resque.redis = @original_redis
15
- end
16
-
17
- test "can set a namespace through a url-like string" do
18
- assert Resque.redis
19
- assert_equal :resque, Resque.redis.namespace
20
- Resque.redis = 'localhost:9736/namespace'
21
- assert_equal 'namespace', Resque.redis.namespace
22
- end
23
-
24
- test "redis= works correctly with a Redis::Namespace param" do
25
- new_redis = Redis.new(:host => "localhost", :port => 9736)
26
- new_namespace = Redis::Namespace.new("namespace", :redis => new_redis)
27
- Resque.redis = new_namespace
28
- assert_equal new_namespace, Resque.redis
29
-
30
- Resque.redis = 'localhost:9736/namespace'
31
- end
32
-
33
- test "can put jobs on a queue" do
34
- assert Resque::Job.create(:jobs, 'SomeJob', 20, '/tmp')
35
- assert Resque::Job.create(:jobs, 'SomeJob', 20, '/tmp')
36
- end
37
-
38
- test "can grab jobs off a queue" do
39
- Resque::Job.create(:jobs, 'some-job', 20, '/tmp')
40
-
41
- job = Resque.reserve(:jobs)
42
-
43
- assert_kind_of Resque::Job, job
44
- assert_equal SomeJob, job.payload_class
45
- assert_equal 20, job.args[0]
46
- assert_equal '/tmp', job.args[1]
47
- end
48
-
49
- test "can re-queue jobs" do
50
- Resque::Job.create(:jobs, 'some-job', 20, '/tmp')
51
-
52
- job = Resque.reserve(:jobs)
53
- job.recreate
54
-
55
- assert_equal job, Resque.reserve(:jobs)
56
- end
57
-
58
- test "can put jobs on a queue by way of an ivar" do
59
- assert_equal 0, Resque.size(:ivar)
60
- assert Resque.enqueue(SomeIvarJob, 20, '/tmp')
61
- assert Resque.enqueue(SomeIvarJob, 20, '/tmp')
62
-
63
- job = Resque.reserve(:ivar)
64
-
65
- assert_kind_of Resque::Job, job
66
- assert_equal SomeIvarJob, job.payload_class
67
- assert_equal 20, job.args[0]
68
- assert_equal '/tmp', job.args[1]
69
-
70
- assert Resque.reserve(:ivar)
71
- assert_equal nil, Resque.reserve(:ivar)
72
- end
73
-
74
- test "can remove jobs from a queue by way of an ivar" do
75
- assert_equal 0, Resque.size(:ivar)
76
- assert Resque.enqueue(SomeIvarJob, 20, '/tmp')
77
- assert Resque.enqueue(SomeIvarJob, 30, '/tmp')
78
- assert Resque.enqueue(SomeIvarJob, 20, '/tmp')
79
- assert Resque::Job.create(:ivar, 'blah-job', 20, '/tmp')
80
- assert Resque.enqueue(SomeIvarJob, 20, '/tmp')
81
- assert_equal 5, Resque.size(:ivar)
82
-
83
- assert Resque.dequeue(SomeIvarJob, 30, '/tmp')
84
- assert_equal 4, Resque.size(:ivar)
85
- assert Resque.dequeue(SomeIvarJob)
86
- assert_equal 1, Resque.size(:ivar)
87
- end
88
-
89
- test "jobs have a nice #inspect" do
90
- assert Resque::Job.create(:jobs, 'SomeJob', 20, '/tmp')
91
- job = Resque.reserve(:jobs)
92
- assert_equal '(Job{jobs} | SomeJob | [20, "/tmp"])', job.inspect
93
- end
94
-
95
- test "jobs can be destroyed" do
96
- assert Resque::Job.create(:jobs, 'SomeJob', 20, '/tmp')
97
- assert Resque::Job.create(:jobs, 'BadJob', 20, '/tmp')
98
- assert Resque::Job.create(:jobs, 'SomeJob', 20, '/tmp')
99
- assert Resque::Job.create(:jobs, 'BadJob', 30, '/tmp')
100
- assert Resque::Job.create(:jobs, 'BadJob', 20, '/tmp')
101
-
102
- assert_equal 5, Resque.size(:jobs)
103
- assert_equal 2, Resque::Job.destroy(:jobs, 'SomeJob')
104
- assert_equal 3, Resque.size(:jobs)
105
- assert_equal 1, Resque::Job.destroy(:jobs, 'BadJob', 30, '/tmp')
106
- assert_equal 2, Resque.size(:jobs)
107
- end
108
-
109
- test "jobs can test for equality" do
110
- assert Resque::Job.create(:jobs, 'SomeJob', 20, '/tmp')
111
- assert Resque::Job.create(:jobs, 'some-job', 20, '/tmp')
112
- assert_equal Resque.reserve(:jobs), Resque.reserve(:jobs)
113
-
114
- assert Resque::Job.create(:jobs, 'SomeMethodJob', 20, '/tmp')
115
- assert Resque::Job.create(:jobs, 'SomeJob', 20, '/tmp')
116
- assert_not_equal Resque.reserve(:jobs), Resque.reserve(:jobs)
117
-
118
- assert Resque::Job.create(:jobs, 'SomeJob', 20, '/tmp')
119
- assert Resque::Job.create(:jobs, 'SomeJob', 30, '/tmp')
120
- assert_not_equal Resque.reserve(:jobs), Resque.reserve(:jobs)
121
- end
122
-
123
- test "can put jobs on a queue by way of a method" do
124
- assert_equal 0, Resque.size(:method)
125
- assert Resque.enqueue(SomeMethodJob, 20, '/tmp')
126
- assert Resque.enqueue(SomeMethodJob, 20, '/tmp')
127
-
128
- job = Resque.reserve(:method)
129
-
130
- assert_kind_of Resque::Job, job
131
- assert_equal SomeMethodJob, job.payload_class
132
- assert_equal 20, job.args[0]
133
- assert_equal '/tmp', job.args[1]
134
-
135
- assert Resque.reserve(:method)
136
- assert_equal nil, Resque.reserve(:method)
137
- end
138
-
139
- test "can define a queue for jobs by way of a method" do
140
- assert_equal 0, Resque.size(:method)
141
- assert Resque.enqueue_to(:new_queue, SomeMethodJob, 20, '/tmp')
142
-
143
- job = Resque.reserve(:new_queue)
144
- assert_equal SomeMethodJob, job.payload_class
145
- assert_equal 20, job.args[0]
146
- assert_equal '/tmp', job.args[1]
147
- end
148
-
149
- test "needs to infer a queue with enqueue" do
150
- assert_raises Resque::NoQueueError do
151
- Resque.enqueue(SomeJob, 20, '/tmp')
152
- end
153
- end
154
-
155
- test "validates job for queue presence" do
156
- assert_raises Resque::NoQueueError do
157
- Resque.validate(SomeJob)
158
- end
159
- end
160
-
161
- test "can put items on a queue" do
162
- assert Resque.push(:people, { 'name' => 'jon' })
163
- end
164
-
165
- test "can pull items off a queue" do
166
- assert_equal({ 'name' => 'chris' }, Resque.pop(:people))
167
- assert_equal({ 'name' => 'bob' }, Resque.pop(:people))
168
- assert_equal({ 'name' => 'mark' }, Resque.pop(:people))
169
- assert_equal nil, Resque.pop(:people)
170
- end
171
-
172
- test "knows how big a queue is" do
173
- assert_equal 3, Resque.size(:people)
174
-
175
- assert_equal({ 'name' => 'chris' }, Resque.pop(:people))
176
- assert_equal 2, Resque.size(:people)
177
-
178
- assert_equal({ 'name' => 'bob' }, Resque.pop(:people))
179
- assert_equal({ 'name' => 'mark' }, Resque.pop(:people))
180
- assert_equal 0, Resque.size(:people)
181
- end
182
-
183
- test "can peek at a queue" do
184
- assert_equal({ 'name' => 'chris' }, Resque.peek(:people))
185
- assert_equal 3, Resque.size(:people)
186
- end
187
-
188
- test "can peek multiple items on a queue" do
189
- assert_equal({ 'name' => 'bob' }, Resque.peek(:people, 1, 1))
190
-
191
- assert_equal([{ 'name' => 'bob' }, { 'name' => 'mark' }], Resque.peek(:people, 1, 2))
192
- assert_equal([{ 'name' => 'chris' }, { 'name' => 'bob' }], Resque.peek(:people, 0, 2))
193
- assert_equal([{ 'name' => 'chris' }, { 'name' => 'bob' }, { 'name' => 'mark' }], Resque.peek(:people, 0, 3))
194
- assert_equal({ 'name' => 'mark' }, Resque.peek(:people, 2, 1))
195
- assert_equal nil, Resque.peek(:people, 3)
196
- assert_equal [], Resque.peek(:people, 3, 2)
197
- end
198
-
199
- test "knows what queues it is managing" do
200
- assert_equal %w( people ), Resque.queues
201
- Resque.push(:cars, { 'make' => 'bmw' })
202
- assert_equal %w( cars people ), Resque.queues
203
- end
204
-
205
- test "queues are always a list" do
206
- Resque.redis.flushall
207
- assert_equal [], Resque.queues
208
- end
209
-
210
- test "can delete a queue" do
211
- Resque.push(:cars, { 'make' => 'bmw' })
212
- assert_equal %w( cars people ), Resque.queues
213
- Resque.remove_queue(:people)
214
- assert_equal %w( cars ), Resque.queues
215
- assert_equal nil, Resque.pop(:people)
216
- end
217
-
218
- test "keeps track of resque keys" do
219
- assert_equal ["queue:people", "queues"].sort, Resque.keys.sort
220
- end
221
-
222
- test "badly wants a class name, too" do
223
- assert_raises Resque::NoClassError do
224
- Resque::Job.create(:jobs, nil)
225
- end
226
- end
227
-
228
- test "keeps stats" do
229
- Resque::Job.create(:jobs, SomeJob, 20, '/tmp')
230
- Resque::Job.create(:jobs, BadJob)
231
- Resque::Job.create(:jobs, GoodJob)
232
-
233
- Resque::Job.create(:others, GoodJob)
234
- Resque::Job.create(:others, GoodJob)
235
-
236
- stats = Resque.info
237
- assert_equal 8, stats[:pending]
238
-
239
- @worker = Resque::Worker.new(:jobs)
240
- @worker.register_worker
241
- 2.times { @worker.process }
242
-
243
- job = @worker.reserve
244
- @worker.working_on job
245
-
246
- stats = Resque.info
247
- assert_equal 1, stats[:working]
248
- assert_equal 1, stats[:workers]
249
-
250
- @worker.done_working
251
-
252
- stats = Resque.info
253
- assert_equal 3, stats[:queues]
254
- assert_equal 3, stats[:processed]
255
- assert_equal 1, stats[:failed]
256
- if ENV.key? 'RESQUE_DISTRIBUTED'
257
- assert_equal [Resque.redis.respond_to?(:server) ? 'localhost:9736, localhost:9737' : 'redis://localhost:9736/0, redis://localhost:9737/0'], stats[:servers]
258
- else
259
- assert_equal [Resque.redis.respond_to?(:server) ? 'localhost:9736' : 'redis://localhost:9736/0'], stats[:servers]
260
- end
261
- end
262
-
263
- test "decode bad json" do
264
- assert_raises Resque::Helpers::DecodeException do
265
- Resque.decode("{\"error\":\"Module not found \\u002\"}")
266
- end
267
- end
268
-
269
- test "inlining jobs" do
270
- begin
271
- Resque.inline = true
272
- Resque.enqueue(SomeIvarJob, 20, '/tmp')
273
- assert_equal 0, Resque.size(:ivar)
274
- ensure
275
- Resque.inline = false
276
- end
277
- end
278
- end
data/test/test_helper.rb DELETED
@@ -1,178 +0,0 @@
1
- require 'rubygems'
2
-
3
- $dir = File.dirname(File.expand_path(__FILE__))
4
- $LOAD_PATH.unshift $dir + '/../lib'
5
- $TESTING = true
6
- require 'test/unit'
7
-
8
- require 'redis/namespace'
9
- require 'resque'
10
-
11
- begin
12
- require 'leftright'
13
- rescue LoadError
14
- end
15
-
16
-
17
- #
18
- # make sure we can run redis
19
- #
20
-
21
- if !system("which redis-server")
22
- puts '', "** can't find `redis-server` in your path"
23
- puts "** try running `sudo rake install`"
24
- abort ''
25
- end
26
-
27
-
28
- #
29
- # start our own redis when the tests start,
30
- # kill it when they end
31
- #
32
-
33
- at_exit do
34
- next if $!
35
-
36
- if defined?(MiniTest)
37
- exit_code = MiniTest::Unit.new.run(ARGV)
38
- else
39
- exit_code = Test::Unit::AutoRunner.run
40
- end
41
-
42
- processes = `ps -A -o pid,command | grep [r]edis-test`.split("\n")
43
- pids = processes.map { |process| process.split(" ")[0] }
44
- puts "Killing test redis server..."
45
- pids.each { |pid| Process.kill("TERM", pid.to_i) }
46
- system("rm -f #{$dir}/dump.rdb #{$dir}/dump-cluster.rdb")
47
- exit exit_code
48
- end
49
-
50
- if ENV.key? 'RESQUE_DISTRIBUTED'
51
- require 'redis/distributed'
52
- puts "Starting redis for testing at localhost:9736 and localhost:9737..."
53
- `redis-server #{$dir}/redis-test.conf`
54
- `redis-server #{$dir}/redis-test-cluster.conf`
55
- r = Redis::Distributed.new(['redis://localhost:9736', 'redis://localhost:9737'])
56
- Resque.redis = Redis::Namespace.new :resque, :redis => r
57
- else
58
- puts "Starting redis for testing at localhost:9736..."
59
- `redis-server #{$dir}/redis-test.conf`
60
- Resque.redis = 'localhost:9736'
61
- end
62
-
63
-
64
- ##
65
- # test/spec/mini 3
66
- # http://gist.github.com/25455
67
- # chris@ozmm.org
68
- #
69
- def context(*args, &block)
70
- return super unless (name = args.first) && block
71
- require 'test/unit'
72
- klass = Class.new(defined?(ActiveSupport::TestCase) ? ActiveSupport::TestCase : Test::Unit::TestCase) do
73
- def self.test(name, &block)
74
- define_method("test_#{name.gsub(/\W/,'_')}", &block) if block
75
- end
76
- def self.xtest(*args) end
77
- def self.setup(&block) define_method(:setup, &block) end
78
- def self.teardown(&block) define_method(:teardown, &block) end
79
- end
80
- (class << klass; self end).send(:define_method, :name) { name.gsub(/\W/,'_') }
81
- klass.class_eval &block
82
- # XXX: In 1.8.x, not all tests will run unless anonymous classes are kept in scope.
83
- ($test_classes ||= []) << klass
84
- end
85
-
86
- ##
87
- # Helper to perform job classes
88
- #
89
- module PerformJob
90
- def perform_job(klass, *args)
91
- resque_job = Resque::Job.new(:testqueue, 'class' => klass, 'args' => args)
92
- resque_job.perform
93
- end
94
- end
95
-
96
- #
97
- # fixture classes
98
- #
99
-
100
- class SomeJob
101
- def self.perform(repo_id, path)
102
- end
103
- end
104
-
105
- class SomeIvarJob < SomeJob
106
- @queue = :ivar
107
- end
108
-
109
- class SomeMethodJob < SomeJob
110
- def self.queue
111
- :method
112
- end
113
- end
114
-
115
- class BadJob
116
- def self.perform
117
- raise "Bad job!"
118
- end
119
- end
120
-
121
- class GoodJob
122
- def self.perform(name)
123
- "Good job, #{name}"
124
- end
125
- end
126
-
127
- class BadJobWithSyntaxError
128
- def self.perform
129
- raise SyntaxError, "Extra Bad job!"
130
- end
131
- end
132
-
133
- class BadFailureBackend < Resque::Failure::Base
134
- def save
135
- raise Exception.new("Failure backend error")
136
- end
137
- end
138
-
139
- def with_failure_backend(failure_backend, &block)
140
- previous_backend = Resque::Failure.backend
141
- Resque::Failure.backend = failure_backend
142
- yield block
143
- ensure
144
- Resque::Failure.backend = previous_backend
145
- end
146
-
147
- require 'time'
148
-
149
- class Time
150
- # Thanks, Timecop
151
- class << self
152
- attr_accessor :fake_time
153
-
154
- alias_method :now_without_mock_time, :now
155
-
156
- def now
157
- fake_time || now_without_mock_time
158
- end
159
- end
160
-
161
- self.fake_time = nil
162
- end
163
-
164
- # From minitest/unit
165
- def capture_io
166
- require 'stringio'
167
-
168
- orig_stdout, orig_stderr = $stdout, $stderr
169
- captured_stdout, captured_stderr = StringIO.new, StringIO.new
170
- $stdout, $stderr = captured_stdout, captured_stderr
171
-
172
- yield
173
-
174
- return captured_stdout.string, captured_stderr.string
175
- ensure
176
- $stdout = orig_stdout
177
- $stderr = orig_stderr
178
- end