resque 1.27.4 → 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 (45) hide show
  1. checksums.yaml +5 -5
  2. data/HISTORY.md +122 -3
  3. data/README.markdown +441 -500
  4. data/bin/resque-web +10 -26
  5. data/lib/resque/data_store.rb +52 -58
  6. data/lib/resque/errors.rb +7 -1
  7. data/lib/resque/failure/airbrake.rb +19 -7
  8. data/lib/resque/failure/multiple.rb +6 -2
  9. data/lib/resque/failure/redis.rb +1 -1
  10. data/lib/resque/failure/redis_multi_queue.rb +1 -1
  11. data/lib/resque/failure.rb +7 -0
  12. data/lib/resque/job.rb +2 -2
  13. data/lib/resque/logging.rb +1 -1
  14. data/lib/resque/railtie.rb +10 -0
  15. data/lib/resque/server/public/jquery-3.6.0.min.js +2 -0
  16. data/lib/resque/server/public/main.js +3 -0
  17. data/lib/resque/server/public/ranger.js +7 -4
  18. data/lib/resque/server/public/style.css +3 -3
  19. data/lib/resque/server/views/error.erb +1 -1
  20. data/lib/resque/server/views/failed.erb +9 -3
  21. data/lib/resque/server/views/failed_job.erb +2 -2
  22. data/lib/resque/server/views/job_class.erb +3 -1
  23. data/lib/resque/server/views/key_string.erb +1 -1
  24. data/lib/resque/server/views/layout.erb +5 -4
  25. data/lib/resque/server/views/next_more.erb +14 -14
  26. data/lib/resque/server/views/queues.erb +6 -6
  27. data/lib/resque/server/views/stats.erb +5 -5
  28. data/lib/resque/server/views/working.erb +7 -7
  29. data/lib/resque/server.rb +11 -119
  30. data/lib/resque/server_helper.rb +185 -0
  31. data/lib/resque/stat.rb +16 -9
  32. data/lib/resque/tasks.rb +3 -11
  33. data/lib/resque/thread_signal.rb +13 -34
  34. data/lib/resque/vendor/utf8_util.rb +2 -8
  35. data/lib/resque/version.rb +1 -1
  36. data/lib/resque/web_runner.rb +374 -0
  37. data/lib/resque/worker.rb +76 -48
  38. data/lib/resque.rb +100 -27
  39. data/lib/tasks/redis.rake +10 -10
  40. metadata +44 -28
  41. data/lib/resque/server/helpers.rb +0 -64
  42. data/lib/resque/server/public/jquery-1.12.4.min.js +0 -5
  43. data/lib/resque/server/test_helper.rb +0 -19
  44. data/lib/resque/vendor/utf8_util/utf8_util_18.rb +0 -91
  45. data/lib/resque/vendor/utf8_util/utf8_util_19.rb +0 -6
data/bin/resque-web CHANGED
@@ -1,31 +1,15 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
4
- begin
5
- require 'vegas'
6
- rescue LoadError
7
- require 'rubygems'
8
- require 'vegas'
9
- end
10
- require 'resque/server'
11
4
 
12
-
13
- Vegas::Runner.new(Resque::Server, 'resque-web', {
14
- :before_run => lambda {|v|
15
- path = (ENV['RESQUECONFIG'] || v.args.first)
16
- load path.to_s.strip if path
17
- }
18
- }) do |runner, opts, app|
19
- opts.on('-N NAMESPACE', "--namespace NAMESPACE", "set the Redis namespace") {|namespace|
20
- runner.logger.info "Using Redis namespace '#{namespace}'"
21
- Resque.redis.namespace = namespace
22
- }
23
- opts.on('-r redis-connection', "--redis redis-connection", "set the Redis connection string") {|redis_conf|
24
- runner.logger.info "Using Redis connection '#{redis_conf}'"
25
- Resque.redis = redis_conf
26
- }
27
- opts.on('-a url-prefix', "--append url-prefix", "set reverse_proxy friendly prefix to links") {|url_prefix|
28
- runner.logger.info "Using URL Prefix '#{url_prefix}'"
29
- Resque::Server.url_prefix = url_prefix
30
- }
5
+ if !!(RUBY_PLATFORM =~ /(mingw|bccwin|wince|mswin32)/i)
6
+ begin
7
+ require 'win32/process'
8
+ rescue
9
+ puts "Sorry, in order to use resque-web on Windows you need the win32-process gem:",
10
+ "gem install win32-process"
11
+ end
31
12
  end
13
+ require 'resque/web_runner'
14
+
15
+ Resque::WebRunner.new(*ARGV)
@@ -44,14 +44,20 @@ module Resque
44
44
  :heartbeat!,
45
45
  :remove_heartbeat,
46
46
  :all_heartbeats,
47
+ :acquire_pruning_dead_worker_lock,
47
48
  :set_worker_payload,
48
49
  :worker_start_time,
49
50
  :worker_done_working
50
51
 
51
- def_delegators :@stats_access, :clear_stat,
52
- :decremet_stat,
53
- :increment_stat,
54
- :stat
52
+ def_delegators :@stats_access, :clear_stat,
53
+ :decrement_stat,
54
+ :increment_stat,
55
+ :stat
56
+
57
+ def decremet_stat(*args)
58
+ warn '[Resque] [Deprecation] Resque::DataStore #decremet_stat method is deprecated (please use #decrement_stat)'
59
+ decrement_stat(*args)
60
+ end
55
61
 
56
62
  # Compatibility with any non-Resque classes that were using Resque.redis as a way to access Redis
57
63
  def method_missing(sym,*args,&block)
@@ -67,19 +73,15 @@ module Resque
67
73
  # Get a string identifying the underlying server.
68
74
  # Probably should be private, but was public so must stay public
69
75
  def identifier
70
- # support 1.x versions of redis-rb
71
- if @redis.respond_to?(:server)
72
- @redis.server
73
- elsif @redis.respond_to?(:nodes) # distributed
74
- @redis.nodes.map { |n| n.id }.join(', ')
75
- else
76
- @redis.client.id
77
- end
76
+ @redis.inspect
78
77
  end
79
78
 
80
- # Force a reconnect to Redis.
79
+ # Force a reconnect to Redis without closing the connection in the parent
80
+ # process after a fork.
81
81
  def reconnect
82
- @redis.client.reconnect
82
+ @redis.disconnect!
83
+ @redis.ping
84
+ nil
83
85
  end
84
86
 
85
87
  # Returns an array of all known Resque keys in Redis. Redis' KEYS operation
@@ -91,34 +93,18 @@ module Resque
91
93
  end
92
94
 
93
95
  def server_time
94
- time, _ = redis_time_available? ? @redis.time : Time.now
96
+ time, _ = @redis.time
95
97
  Time.at(time)
96
98
  end
97
99
 
98
- # only needed until support for Redis 2.4 is removed
99
- def redis_time_available?
100
- if @redis_time_available.nil? && !Resque.inline
101
- begin
102
- @redis_time_available = @redis.time
103
- rescue Redis::CommandError
104
- @redis_time_available = false
105
- end
106
- elsif Resque.inline
107
- false
108
- else
109
- @redis_time_available
110
- end
111
- end
112
- private :redis_time_available?
113
-
114
100
  class QueueAccess
115
101
  def initialize(redis)
116
102
  @redis = redis
117
103
  end
118
104
  def push_to_queue(queue,encoded_item)
119
- @redis.pipelined do
120
- watch_queue(queue)
121
- @redis.rpush redis_key_for_queue(queue), encoded_item
105
+ @redis.pipelined do |piped|
106
+ watch_queue(queue, redis: piped)
107
+ piped.rpush redis_key_for_queue(queue), encoded_item
122
108
  end
123
109
  end
124
110
 
@@ -145,9 +131,9 @@ module Resque
145
131
  end
146
132
 
147
133
  def remove_queue(queue)
148
- @redis.pipelined do
149
- @redis.srem(:queues, queue.to_s)
150
- @redis.del(redis_key_for_queue(queue))
134
+ @redis.pipelined do |piped|
135
+ piped.srem(:queues, [queue.to_s])
136
+ piped.del(redis_key_for_queue(queue))
151
137
  end
152
138
  end
153
139
 
@@ -161,8 +147,8 @@ module Resque
161
147
  end
162
148
 
163
149
  # Private: do not call
164
- def watch_queue(queue)
165
- @redis.sadd(:queues, queue.to_s)
150
+ def watch_queue(queue, redis: @redis)
151
+ redis.sadd(:queues, [queue.to_s])
166
152
  end
167
153
 
168
154
  # Private: do not call
@@ -188,7 +174,7 @@ module Resque
188
174
  end
189
175
 
190
176
  def add_failed_queue(failed_queue_name)
191
- @redis.sadd(:failed_queues, failed_queue_name)
177
+ @redis.sadd(:failed_queues, [failed_queue_name])
192
178
  end
193
179
 
194
180
  def remove_failed_queue(failed_queue_name=:failed)
@@ -253,24 +239,24 @@ module Resque
253
239
  end
254
240
 
255
241
  def register_worker(worker)
256
- @redis.pipelined do
257
- @redis.sadd(:workers, worker)
258
- worker_started(worker)
242
+ @redis.pipelined do |piped|
243
+ piped.sadd(:workers, [worker.id])
244
+ worker_started(worker, redis: piped)
259
245
  end
260
246
  end
261
247
 
262
- def worker_started(worker)
263
- @redis.set(redis_key_for_worker_start_time(worker), Time.now.to_s)
248
+ def worker_started(worker, redis: @redis)
249
+ redis.set(redis_key_for_worker_start_time(worker), Time.now.to_s)
264
250
  end
265
251
 
266
252
  def unregister_worker(worker, &block)
267
- @redis.pipelined do
268
- @redis.srem(:workers, worker)
269
- @redis.del(redis_key_for_worker(worker))
270
- @redis.del(redis_key_for_worker_start_time(worker))
271
- @redis.hdel(HEARTBEAT_KEY, worker.to_s)
253
+ @redis.pipelined do |piped|
254
+ piped.srem(:workers, [worker.id])
255
+ piped.del(redis_key_for_worker(worker))
256
+ piped.del(redis_key_for_worker_start_time(worker))
257
+ piped.hdel(HEARTBEAT_KEY, worker.to_s)
272
258
 
273
- block.call
259
+ block.call redis: piped
274
260
  end
275
261
  end
276
262
 
@@ -291,6 +277,10 @@ module Resque
291
277
  @redis.hgetall(HEARTBEAT_KEY)
292
278
  end
293
279
 
280
+ def acquire_pruning_dead_worker_lock(worker, expiry)
281
+ @redis.set(redis_key_for_worker_pruning, worker.to_s, :ex => expiry, :nx => true)
282
+ end
283
+
294
284
  def set_worker_payload(worker, data)
295
285
  @redis.set(redis_key_for_worker(worker), data)
296
286
  end
@@ -300,9 +290,9 @@ module Resque
300
290
  end
301
291
 
302
292
  def worker_done_working(worker, &block)
303
- @redis.pipelined do
304
- @redis.del(redis_key_for_worker(worker))
305
- block.call
293
+ @redis.pipelined do |piped|
294
+ piped.del(redis_key_for_worker(worker))
295
+ block.call redis: piped
306
296
  end
307
297
  end
308
298
 
@@ -315,6 +305,10 @@ module Resque
315
305
  def redis_key_for_worker_start_time(worker)
316
306
  "#{redis_key_for_worker(worker)}:started"
317
307
  end
308
+
309
+ def redis_key_for_worker_pruning
310
+ "pruning_dead_workers_in_progress"
311
+ end
318
312
  end
319
313
 
320
314
  class StatsAccess
@@ -325,16 +319,16 @@ module Resque
325
319
  @redis.get("stat:#{stat}").to_i
326
320
  end
327
321
 
328
- def increment_stat(stat, by = 1)
329
- @redis.incrby("stat:#{stat}", by)
322
+ def increment_stat(stat, by = 1, redis: @redis)
323
+ redis.incrby("stat:#{stat}", by)
330
324
  end
331
325
 
332
326
  def decremet_stat(stat, by = 1)
333
327
  @redis.decrby("stat:#{stat}", by)
334
328
  end
335
329
 
336
- def clear_stat(stat)
337
- @redis.del("stat:#{stat}")
330
+ def clear_stat(stat, redis: @redis)
331
+ redis.del("stat:#{stat}")
338
332
  end
339
333
  end
340
334
  end
data/lib/resque/errors.rb CHANGED
@@ -14,7 +14,13 @@ module Resque
14
14
  super message
15
15
  end
16
16
  end
17
- class PruneDeadWorkerDirtyExit < DirtyExit; end
17
+
18
+ class PruneDeadWorkerDirtyExit < DirtyExit
19
+ def initialize(hostname, job)
20
+ job ||= "<Unknown Job>"
21
+ super("Worker #{hostname} did not gracefully exit while processing #{job}")
22
+ end
23
+ end
18
24
 
19
25
  # Raised when child process is TERM'd so job can rescue this to do shutdown work.
20
26
  class TermException < SignalException; end
@@ -9,7 +9,7 @@ module Resque
9
9
  class Airbrake < Base
10
10
  def self.configure(&block)
11
11
  Resque.logger.warn "This actually sets global Airbrake configuration, " \
12
- "which is probably not what you want. This will be gone in 2.0."
12
+ "which is probably not what you want."
13
13
  Resque::Failure.backend = self
14
14
  ::Airbrake.configure(&block)
15
15
  end
@@ -21,12 +21,24 @@ module Resque
21
21
  end
22
22
 
23
23
  def save
24
- ::Airbrake.notify(exception,
25
- :parameters => {
26
- :payload_class => payload['class'].to_s,
27
- :payload_args => payload['args'].inspect
28
- }
29
- )
24
+ notify(
25
+ exception,
26
+ parameters: {
27
+ payload_class: payload['class'].to_s,
28
+ payload_args: payload['args'].inspect
29
+ }
30
+ )
31
+ end
32
+
33
+ private
34
+
35
+ def notify(exception, options)
36
+ if ::Airbrake.respond_to?(:notify_sync)
37
+ ::Airbrake.notify_sync(exception, options)
38
+ else
39
+ # Older versions of Airbrake (< 5)
40
+ ::Airbrake.notify(exception, options)
41
+ end
30
42
  end
31
43
  end
32
44
  end
@@ -60,8 +60,12 @@ module Resque
60
60
  classes.first.requeue_all
61
61
  end
62
62
 
63
- def self.remove(index, queue)
64
- classes.each { |klass| klass.remove(index) }
63
+ def self.requeue_queue(queue)
64
+ classes.first.requeue_queue(queue)
65
+ end
66
+
67
+ def self.remove(index, queue = nil)
68
+ classes.each { |klass| klass.remove(index, queue) }
65
69
  end
66
70
  end
67
71
  end
@@ -31,7 +31,7 @@ module Resque
31
31
 
32
32
  if class_name
33
33
  n = 0
34
- each(0, count(queue), queue, class_name) { n += 1 }
34
+ each(0, count(queue), queue, class_name) { n += 1 }
35
35
  n
36
36
  else
37
37
  data_store.num_failed
@@ -60,7 +60,7 @@ module Resque
60
60
  end
61
61
  items.each_with_index do |item, i|
62
62
  if !class_name || (item['payload'] && item['payload']['class'] == class_name)
63
- id = reversed ? (items.length - 1) - (offset + i) : offset + i
63
+ id = reversed ? (items.length - 1) + (offset - i) : offset + i
64
64
  yield id, item
65
65
  end
66
66
  end
@@ -27,6 +27,7 @@ module Resque
27
27
  def self.backend=(backend)
28
28
  @backend = backend
29
29
  end
30
+ self.backend = nil
30
31
 
31
32
  # Returns the current backend class. If none has been set, falls
32
33
  # back to `Resque::Failure::Redis`
@@ -90,6 +91,12 @@ module Resque
90
91
  backend.clear(queue)
91
92
  end
92
93
 
94
+ def self.clear_retried
95
+ each do |index, job|
96
+ remove(index) unless job['retried_at'].nil?
97
+ end
98
+ end
99
+
93
100
  def self.requeue(id, queue = nil)
94
101
  backend.requeue(id, queue)
95
102
  end
data/lib/resque/job.rb CHANGED
@@ -48,7 +48,7 @@ module Resque
48
48
  def self.decode(object)
49
49
  Resque.decode(object)
50
50
  end
51
-
51
+
52
52
  # Given a word with dashes, returns a camel cased version of it.
53
53
  def classify(dashed_word)
54
54
  Resque.classify(dashed_word)
@@ -154,7 +154,7 @@ module Resque
154
154
 
155
155
  begin
156
156
  # Execute before_perform hook. Abort the job gracefully if
157
- # Resque::DontPerform is raised.
157
+ # Resque::Job::DontPerform is raised.
158
158
  begin
159
159
  before_hooks.each do |hook|
160
160
  job.send(hook, *job_args)
@@ -7,7 +7,7 @@ module Resque
7
7
  def self.log(severity, message)
8
8
  Resque.logger.__send__(severity, message) if Resque.logger
9
9
  end
10
-
10
+
11
11
  # Log level aliases
12
12
  def debug(message); Logging.log :debug, message; end
13
13
  def info(message); Logging.log :info, message; end
@@ -0,0 +1,10 @@
1
+ module Resque
2
+ class Railtie < Rails::Railtie
3
+ rake_tasks do
4
+ require 'resque/tasks'
5
+
6
+ # redefine ths task to load the rails env
7
+ task "resque:setup" => :environment
8
+ end
9
+ end
10
+ end