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.
- checksums.yaml +5 -5
- data/HISTORY.md +122 -3
- data/README.markdown +441 -500
- data/bin/resque-web +10 -26
- data/lib/resque/data_store.rb +52 -58
- data/lib/resque/errors.rb +7 -1
- data/lib/resque/failure/airbrake.rb +19 -7
- data/lib/resque/failure/multiple.rb +6 -2
- data/lib/resque/failure/redis.rb +1 -1
- data/lib/resque/failure/redis_multi_queue.rb +1 -1
- data/lib/resque/failure.rb +7 -0
- data/lib/resque/job.rb +2 -2
- data/lib/resque/logging.rb +1 -1
- data/lib/resque/railtie.rb +10 -0
- data/lib/resque/server/public/jquery-3.6.0.min.js +2 -0
- data/lib/resque/server/public/main.js +3 -0
- data/lib/resque/server/public/ranger.js +7 -4
- data/lib/resque/server/public/style.css +3 -3
- data/lib/resque/server/views/error.erb +1 -1
- data/lib/resque/server/views/failed.erb +9 -3
- data/lib/resque/server/views/failed_job.erb +2 -2
- data/lib/resque/server/views/job_class.erb +3 -1
- data/lib/resque/server/views/key_string.erb +1 -1
- data/lib/resque/server/views/layout.erb +5 -4
- data/lib/resque/server/views/next_more.erb +14 -14
- data/lib/resque/server/views/queues.erb +6 -6
- data/lib/resque/server/views/stats.erb +5 -5
- data/lib/resque/server/views/working.erb +7 -7
- data/lib/resque/server.rb +11 -119
- data/lib/resque/server_helper.rb +185 -0
- data/lib/resque/stat.rb +16 -9
- data/lib/resque/tasks.rb +3 -11
- data/lib/resque/thread_signal.rb +13 -34
- data/lib/resque/vendor/utf8_util.rb +2 -8
- data/lib/resque/version.rb +1 -1
- data/lib/resque/web_runner.rb +374 -0
- data/lib/resque/worker.rb +76 -48
- data/lib/resque.rb +100 -27
- data/lib/tasks/redis.rake +10 -10
- metadata +44 -28
- data/lib/resque/server/helpers.rb +0 -64
- data/lib/resque/server/public/jquery-1.12.4.min.js +0 -5
- data/lib/resque/server/test_helper.rb +0 -19
- data/lib/resque/vendor/utf8_util/utf8_util_18.rb +0 -91
- 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
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
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)
|
data/lib/resque/data_store.rb
CHANGED
@@ -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
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
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
|
-
|
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.
|
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, _ =
|
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
|
-
|
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
|
-
|
150
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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.
|
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
|
-
|
25
|
-
|
26
|
-
|
27
|
-
:
|
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.
|
64
|
-
classes.
|
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
|
data/lib/resque/failure/redis.rb
CHANGED
@@ -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)
|
63
|
+
id = reversed ? (items.length - 1) + (offset - i) : offset + i
|
64
64
|
yield id, item
|
65
65
|
end
|
66
66
|
end
|
data/lib/resque/failure.rb
CHANGED
@@ -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)
|
data/lib/resque/logging.rb
CHANGED