resque 1.24.1 → 1.25.0.pre
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of resque might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/HISTORY.md +25 -1
- data/README.markdown +14 -56
- data/lib/resque.rb +47 -5
- data/lib/resque/failure.rb +4 -4
- data/lib/resque/failure/airbrake.rb +20 -4
- data/lib/resque/failure/base.rb +1 -1
- data/lib/resque/failure/redis.rb +15 -4
- data/lib/resque/failure/redis_multi_queue.rb +7 -4
- data/lib/resque/helpers.rb +8 -1
- data/lib/resque/job.rb +120 -3
- data/lib/resque/server.rb +3 -1
- data/lib/resque/server/helpers.rb +6 -2
- data/lib/resque/server/views/failed.erb +2 -1
- data/lib/resque/server/views/layout.erb +2 -2
- data/lib/resque/server/views/next_more.erb +7 -7
- data/lib/resque/stat.rb +5 -1
- data/lib/resque/tasks.rb +1 -1
- data/lib/resque/version.rb +1 -1
- data/lib/resque/worker.rb +119 -35
- data/test/failure_base_test.rb +15 -0
- data/test/test_helper.rb +2 -0
- data/test/worker_test.rb +56 -2
- metadata +49 -52
- data/lib/resque/failure/hoptoad.rb +0 -33
- data/lib/resque/failure/thoughtbot.rb +0 -33
- data/test/dump.rdb +0 -0
- data/test/hoptoad_test.rb +0 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e28312bcc43dec49cd4dae52b64416413436da85
|
4
|
+
data.tar.gz: 489f3640b552d6d9ea6987732b86427a42aec182
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3c9d30888178238ed2117f3991d83d204a7cbec53943631637353bc62103b0cd0b63fd2fe93ce60657ed883f1f4664e947745f419f1398671dee5c034fbc3aca
|
7
|
+
data.tar.gz: 9c7fda8c5677603ccde7ef5c2c35b19d6b7106d6309e1d3c032afc03730e7db8d80c50400924785d46376784cfc87f2a28797399f4385381d56b667ea10a6f0e
|
data/HISTORY.md
CHANGED
@@ -1,3 +1,28 @@
|
|
1
|
+
## 1.25.0 (TBD)
|
2
|
+
* Updates fork method so [resque-multi-job-forks](https://github.com/stulentsev/resque-multi-job-forks)
|
3
|
+
monkey patching works again. See discussion at https://github.com/defunkt/resque/pull/895 for more
|
4
|
+
context (@jonhyman)
|
5
|
+
* Use Redis.pipelined to group batches of redis commands.
|
6
|
+
https://github.com/resque/resque/pull/902 (@jonhyman)
|
7
|
+
* Fixed uninitialize constant for the module/class that contains the perform
|
8
|
+
method causing job failures to no be reported, #792 (@sideshowcoder)
|
9
|
+
* Fix Resque::Failure::Base.all to have the correct signature.
|
10
|
+
(@rentalutions)
|
11
|
+
* Don't close stdio pipes when daemonizing so as to not hide errors. #967
|
12
|
+
(@sideshowcoder)
|
13
|
+
* Fix for worker_pids on Windows. #980 (@kzgs)
|
14
|
+
* Only prune workers for queues the current worker knows about. #1000
|
15
|
+
(!) (@dsabanin)
|
16
|
+
* Handle duplicate TERM signals. #988 (@softwaregravy)
|
17
|
+
* Fix issue with exiting workers and unintentionally deregistering the
|
18
|
+
parent when the forked child exits. #1017 (@magec)
|
19
|
+
* Fix encoding errors with local date formatting. #1065 (@katafrakt)
|
20
|
+
* Fix CI for 1.8.7 and 1.9.2 modes due to dependencies. #1090
|
21
|
+
(@adelcambre)
|
22
|
+
* Allow using globs for queue names to listen on, allowing things like
|
23
|
+
listening on `staging_*`. #1085 (@adelcambre)
|
24
|
+
|
25
|
+
|
1
26
|
## 1.24.1 (2013-3-23)
|
2
27
|
|
3
28
|
* Adds a default value for `per_page` on resque-server for plugins which add tabs (@jonhyman)
|
@@ -37,7 +62,6 @@
|
|
37
62
|
typing purposes (jonhyman)
|
38
63
|
* Fix log formatters not appending a new line (flavorpill)
|
39
64
|
* redirect unauthorized resque-web polling requests to root url (trliner)
|
40
|
-
* Disable forking with FORK_PER_JOB=false (@tarcieri)
|
41
65
|
* Various resque-web fixes (@tarcieri)
|
42
66
|
* Optional RedisMultiQueue failure backend, can be enabled with
|
43
67
|
FAILURE_BACKEND=redis_multi_queue env var (@tarcieri)
|
data/README.markdown
CHANGED
@@ -193,7 +193,7 @@ If a job raises an exception, it is logged and handed off to the
|
|
193
193
|
`Resque::Failure` module. Failures are logged either locally in Redis
|
194
194
|
or using some different backend.
|
195
195
|
|
196
|
-
For example, Resque ships with
|
196
|
+
For example, Resque ships with Airbrake support.
|
197
197
|
|
198
198
|
Keep this in mind when writing your jobs: you may want to throw
|
199
199
|
exceptions you would not normally throw in order to assist debugging.
|
@@ -338,7 +338,7 @@ so using the `resque:workers` rake task:
|
|
338
338
|
|
339
339
|
$ COUNT=5 QUEUE=* rake resque:workers
|
340
340
|
|
341
|
-
This will spawn five Resque workers, each in its own
|
341
|
+
This will spawn five Resque workers, each in its own process. Hitting
|
342
342
|
ctrl-c should be sufficient to stop them all.
|
343
343
|
|
344
344
|
|
@@ -543,48 +543,6 @@ Choose DelayedJob if:
|
|
543
543
|
In no way is Resque a "better" DelayedJob, so make sure you pick the
|
544
544
|
tool that's best for your app.
|
545
545
|
|
546
|
-
|
547
|
-
Installing Redis
|
548
|
-
----------------
|
549
|
-
|
550
|
-
Resque requires Redis 0.900 or higher.
|
551
|
-
|
552
|
-
Resque uses Redis' lists for its queues. It also stores worker state
|
553
|
-
data in Redis.
|
554
|
-
|
555
|
-
#### Homebrew
|
556
|
-
|
557
|
-
If you're on OS X, Homebrew is the simplest way to install Redis:
|
558
|
-
|
559
|
-
$ brew install redis
|
560
|
-
$ redis-server /usr/local/etc/redis.conf
|
561
|
-
|
562
|
-
You now have a Redis daemon running on 6379.
|
563
|
-
|
564
|
-
#### Via Resque
|
565
|
-
|
566
|
-
Resque includes Rake tasks (thanks to Ezra's redis-rb) that will
|
567
|
-
install and run Redis for you:
|
568
|
-
|
569
|
-
$ git clone git://github.com/defunkt/resque.git
|
570
|
-
$ cd resque
|
571
|
-
$ rake redis:install dtach:install
|
572
|
-
$ rake redis:start
|
573
|
-
|
574
|
-
Or, if you don't have admin access on your machine:
|
575
|
-
|
576
|
-
$ git clone git://github.com/defunkt/resque.git
|
577
|
-
$ cd resque
|
578
|
-
$ PREFIX=<your_prefix> rake redis:install dtach:install
|
579
|
-
$ rake redis:start
|
580
|
-
|
581
|
-
You now have Redis running on 6379. Wait a second then hit ctrl-\ to
|
582
|
-
detach and keep it running in the background.
|
583
|
-
|
584
|
-
The demo is probably the best way to figure out how to put the parts
|
585
|
-
together. But, it's not that hard.
|
586
|
-
|
587
|
-
|
588
546
|
Resque Dependencies
|
589
547
|
-------------------
|
590
548
|
|
@@ -662,7 +620,7 @@ Don't forget you can define a `resque:setup` hook in
|
|
662
620
|
|
663
621
|
### In a Rails 2.x app, as a plugin
|
664
622
|
|
665
|
-
$ ./script/plugin install git://github.com/
|
623
|
+
$ ./script/plugin install git://github.com/resque/resque
|
666
624
|
|
667
625
|
That's it! Resque will automatically be available when your Rails app
|
668
626
|
loads.
|
@@ -764,11 +722,11 @@ Plugins and Hooks
|
|
764
722
|
-----------------
|
765
723
|
|
766
724
|
For a list of available plugins see
|
767
|
-
<http://wiki.github.com/
|
725
|
+
<http://wiki.github.com/resque/resque/plugins>.
|
768
726
|
|
769
727
|
If you'd like to write your own plugin, or want to customize Resque
|
770
728
|
using hooks (such as `Resque.after_fork`), see
|
771
|
-
[docs/HOOKS.md](http://github.com/
|
729
|
+
[docs/HOOKS.md](http://github.com/resque/resque/blob/master/docs/HOOKS.md).
|
772
730
|
|
773
731
|
|
774
732
|
Namespaces
|
@@ -820,7 +778,7 @@ send patches for any tweaks or improvements you can make to it.
|
|
820
778
|
Questions
|
821
779
|
---------
|
822
780
|
|
823
|
-
Please add them to the [FAQ](https://github.com/
|
781
|
+
Please add them to the [FAQ](https://github.com/resque/resque/wiki/FAQ) or
|
824
782
|
ask on the Mailing List. The Mailing List is explained further below
|
825
783
|
|
826
784
|
|
@@ -831,7 +789,7 @@ Want to hack on Resque?
|
|
831
789
|
|
832
790
|
First clone the repo and run the tests:
|
833
791
|
|
834
|
-
git clone git://github.com/
|
792
|
+
git clone git://github.com/resque/resque.git
|
835
793
|
cd resque
|
836
794
|
rake test
|
837
795
|
|
@@ -884,10 +842,10 @@ The archive can be found at <http://librelist.com/browser/resque/>.
|
|
884
842
|
Meta
|
885
843
|
----
|
886
844
|
|
887
|
-
* Code: `git clone git://github.com/
|
888
|
-
* Home: <http://github.com/
|
889
|
-
* Docs: <http://
|
890
|
-
* Bugs: <http://github.com/
|
845
|
+
* Code: `git clone git://github.com/resque/resque.git`
|
846
|
+
* Home: <http://github.com/resque/resque>
|
847
|
+
* Docs: <http://resque.github.com/resque/>
|
848
|
+
* Bugs: <http://github.com/resque/resque/issues>
|
891
849
|
* List: <resque@librelist.com>
|
892
850
|
* Chat: <irc://irc.freenode.net/resque>
|
893
851
|
* Gems: <http://gemcutter.org/gems/resque>
|
@@ -902,7 +860,7 @@ Chris Wanstrath :: chris@ozmm.org :: @defunkt
|
|
902
860
|
|
903
861
|
[0]: http://github.com/blog/542-introducing-resque
|
904
862
|
[1]: http://help.github.com/forking/
|
905
|
-
[2]: http://github.com/
|
863
|
+
[2]: http://github.com/resque/resque/issues
|
906
864
|
[sv]: http://semver.org/
|
907
|
-
[rs]: http://github.com/
|
908
|
-
[cb]: http://wiki.github.com/
|
865
|
+
[rs]: http://github.com/resque/redis-namespace
|
866
|
+
[cb]: http://wiki.github.com/resque/resque/contributing
|
data/lib/resque.rb
CHANGED
@@ -21,9 +21,47 @@ require 'resque/plugin'
|
|
21
21
|
require 'resque/vendor/utf8_util'
|
22
22
|
|
23
23
|
module Resque
|
24
|
-
include Helpers
|
25
24
|
extend self
|
26
25
|
|
26
|
+
# Given a Ruby object, returns a string suitable for storage in a
|
27
|
+
# queue.
|
28
|
+
def encode(object)
|
29
|
+
if MultiJson.respond_to?(:dump) && MultiJson.respond_to?(:load)
|
30
|
+
MultiJson.dump object
|
31
|
+
else
|
32
|
+
MultiJson.encode object
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# Given a string, returns a Ruby object.
|
37
|
+
def decode(object)
|
38
|
+
return unless object
|
39
|
+
|
40
|
+
begin
|
41
|
+
if MultiJson.respond_to?(:dump) && MultiJson.respond_to?(:load)
|
42
|
+
MultiJson.load object
|
43
|
+
else
|
44
|
+
MultiJson.decode object
|
45
|
+
end
|
46
|
+
rescue ::MultiJson::DecodeError => e
|
47
|
+
raise Helpers::DecodeException, e.message, e.backtrace
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
extend Forwardable
|
52
|
+
|
53
|
+
def self.config=(options = {})
|
54
|
+
@config = Config.new(options)
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.config
|
58
|
+
@config ||= Config.new
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.configure
|
62
|
+
yield config
|
63
|
+
end
|
64
|
+
|
27
65
|
# Accepts:
|
28
66
|
# 1. A 'hostname:port' String
|
29
67
|
# 2. A 'hostname:port:db' String (to select the Redis db)
|
@@ -169,8 +207,10 @@ module Resque
|
|
169
207
|
#
|
170
208
|
# Returns nothing
|
171
209
|
def push(queue, item)
|
172
|
-
|
173
|
-
|
210
|
+
redis.pipelined do
|
211
|
+
watch_queue(queue)
|
212
|
+
redis.rpush "queue:#{queue}", encode(item)
|
213
|
+
end
|
174
214
|
end
|
175
215
|
|
176
216
|
# Pops a job off a queue. Queue name should be a string.
|
@@ -217,8 +257,10 @@ module Resque
|
|
217
257
|
|
218
258
|
# Given a queue name, completely deletes the queue.
|
219
259
|
def remove_queue(queue)
|
220
|
-
redis.
|
221
|
-
|
260
|
+
redis.pipelined do
|
261
|
+
redis.srem(:queues, queue.to_s)
|
262
|
+
redis.del("queue:#{queue}")
|
263
|
+
end
|
222
264
|
end
|
223
265
|
|
224
266
|
# Used internally to keep track of which queues we've created.
|
data/lib/resque/failure.rb
CHANGED
@@ -22,8 +22,8 @@ module Resque
|
|
22
22
|
# `Resque::Failure::Base`.
|
23
23
|
#
|
24
24
|
# Example use:
|
25
|
-
# require 'resque/failure/
|
26
|
-
# Resque::Failure.backend = Resque::Failure::
|
25
|
+
# require 'resque/failure/airbrake'
|
26
|
+
# Resque::Failure.backend = Resque::Failure::Airbrake
|
27
27
|
def self.backend=(backend)
|
28
28
|
@backend = backend
|
29
29
|
end
|
@@ -76,8 +76,8 @@ module Resque
|
|
76
76
|
end
|
77
77
|
|
78
78
|
# Iterate across all failures with the given options
|
79
|
-
def self.each(offset = 0, limit = self.count, queue = nil, class_name = nil, &block)
|
80
|
-
backend.each(offset, limit, queue, class_name, &block)
|
79
|
+
def self.each(offset = 0, limit = self.count, queue = nil, class_name = nil, order = 'desc', &block)
|
80
|
+
backend.each(offset, limit, queue, class_name, order, &block)
|
81
81
|
end
|
82
82
|
|
83
83
|
# The string url of the backend's web interface, if any.
|
@@ -4,14 +4,30 @@ rescue LoadError
|
|
4
4
|
raise "Can't find 'airbrake' gem. Please add it to your Gemfile or install it."
|
5
5
|
end
|
6
6
|
|
7
|
-
require 'resque/failure/thoughtbot'
|
8
|
-
|
9
7
|
module Resque
|
10
8
|
module Failure
|
11
9
|
class Airbrake < Base
|
12
|
-
|
10
|
+
def self.configure(&block)
|
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."
|
13
|
+
Resque::Failure.backend = self
|
14
|
+
::Airbrake.configure(&block)
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.count(queue = nil, class_name = nil)
|
18
|
+
# We can't get the total # of errors from Airbrake so we fake it
|
19
|
+
# by asking Resque how many errors it has seen.
|
20
|
+
Stat[:failed]
|
21
|
+
end
|
13
22
|
|
14
|
-
|
23
|
+
def save
|
24
|
+
::Airbrake.notify_or_ignore(exception,
|
25
|
+
:parameters => {
|
26
|
+
:payload_class => payload['class'].to_s,
|
27
|
+
:payload_args => payload['args'].inspect
|
28
|
+
}
|
29
|
+
)
|
30
|
+
end
|
15
31
|
end
|
16
32
|
end
|
17
33
|
end
|
data/lib/resque/failure/base.rb
CHANGED
data/lib/resque/failure/redis.rb
CHANGED
@@ -5,7 +5,7 @@ module Resque
|
|
5
5
|
class Redis < Base
|
6
6
|
def save
|
7
7
|
data = {
|
8
|
-
:failed_at => Time.now.strftime("%Y/%m/%d %H:%M:%S %Z"),
|
8
|
+
:failed_at => UTF8Util.clean(Time.now.strftime("%Y/%m/%d %H:%M:%S %Z")),
|
9
9
|
:payload => payload,
|
10
10
|
:exception => exception.class.to_s,
|
11
11
|
:error => UTF8Util.clean(exception.to_s),
|
@@ -38,10 +38,21 @@ module Resque
|
|
38
38
|
Resque.list_range(:failed, offset, limit)
|
39
39
|
end
|
40
40
|
|
41
|
-
def self.each(offset = 0, limit = self.count, queue = :failed, class_name = nil)
|
42
|
-
Array(all(offset, limit, queue))
|
41
|
+
def self.each(offset = 0, limit = self.count, queue = :failed, class_name = nil, order = 'desc')
|
42
|
+
all_items = Array(all(offset, limit, queue))
|
43
|
+
reversed = false
|
44
|
+
if order.eql? 'desc'
|
45
|
+
all_items.reverse!
|
46
|
+
reversed = true
|
47
|
+
end
|
48
|
+
all_items.each_with_index do |item, i|
|
43
49
|
if !class_name || (item['payload'] && item['payload']['class'] == class_name)
|
44
|
-
|
50
|
+
if reversed
|
51
|
+
id = (all_items.length - 1) - (offset + i)
|
52
|
+
else
|
53
|
+
id = offset + i
|
54
|
+
end
|
55
|
+
yield id, item
|
45
56
|
end
|
46
57
|
end
|
47
58
|
end
|
@@ -33,17 +33,20 @@ module Resque
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
-
def self.all(offset = 0, limit = 1, queue = :failed)
|
37
|
-
Resque.list_range(queue, offset, limit)
|
36
|
+
def self.all(offset = 0, limit = 1, queue = :failed, order = 'desc')
|
37
|
+
Resque.list_range(queue, offset, limit, order)
|
38
38
|
end
|
39
39
|
|
40
40
|
def self.queues
|
41
41
|
Array(Resque.redis.smembers(:failed_queues))
|
42
42
|
end
|
43
43
|
|
44
|
-
def self.each(offset = 0, limit = self.count, queue = :failed, class_name = nil)
|
45
|
-
items = all(offset, limit, queue)
|
44
|
+
def self.each(offset = 0, limit = self.count, queue = :failed, class_name = nil, order = 'desc')
|
45
|
+
items = all(offset, limit, queue, order)
|
46
46
|
items = [items] unless items.is_a? Array
|
47
|
+
if order.eql? 'desc'
|
48
|
+
items.reverse!
|
49
|
+
end
|
47
50
|
items.each_with_index do |item, i|
|
48
51
|
if !class_name || (item['payload'] && item['payload']['class'] == class_name)
|
49
52
|
yield offset + i, item
|
data/lib/resque/helpers.rb
CHANGED
@@ -11,6 +11,14 @@ end
|
|
11
11
|
module Resque
|
12
12
|
# Methods used by various classes in Resque.
|
13
13
|
module Helpers
|
14
|
+
def self.extended(parent_class)
|
15
|
+
warn("Resque::Helpers will be gone with no replacement in Resque 2.0.0.")
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.included(parent_class)
|
19
|
+
warn("Resque::Helpers will be gone with no replacement in Resque 2.0.0.")
|
20
|
+
end
|
21
|
+
|
14
22
|
class DecodeException < StandardError; end
|
15
23
|
|
16
24
|
# Direct access to the Redis instance.
|
@@ -26,7 +34,6 @@ module Resque
|
|
26
34
|
else
|
27
35
|
MultiJson.encode object
|
28
36
|
end
|
29
|
-
|
30
37
|
end
|
31
38
|
|
32
39
|
# Given a string, returns a Ruby object.
|
data/lib/resque/job.rb
CHANGED
@@ -12,8 +12,110 @@ module Resque
|
|
12
12
|
# klass = Resque::Job.constantize(job.payload['class'])
|
13
13
|
# klass.perform(*job.payload['args'])
|
14
14
|
class Job
|
15
|
-
|
16
|
-
|
15
|
+
def redis
|
16
|
+
Resque.redis
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.redis
|
20
|
+
Resque.redis
|
21
|
+
end
|
22
|
+
|
23
|
+
# Given a Ruby object, returns a string suitable for storage in a
|
24
|
+
# queue.
|
25
|
+
def encode(object)
|
26
|
+
if MultiJson.respond_to?(:dump) && MultiJson.respond_to?(:load)
|
27
|
+
MultiJson.dump object
|
28
|
+
else
|
29
|
+
MultiJson.encode object
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Given a string, returns a Ruby object.
|
34
|
+
def decode(object)
|
35
|
+
return unless object
|
36
|
+
|
37
|
+
begin
|
38
|
+
if MultiJson.respond_to?(:dump) && MultiJson.respond_to?(:load)
|
39
|
+
MultiJson.load object
|
40
|
+
else
|
41
|
+
MultiJson.decode object
|
42
|
+
end
|
43
|
+
rescue ::MultiJson::DecodeError => e
|
44
|
+
raise DecodeException, e.message, e.backtrace
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Given a Ruby object, returns a string suitable for storage in a
|
49
|
+
# queue.
|
50
|
+
def self.encode(object)
|
51
|
+
if MultiJson.respond_to?(:dump) && MultiJson.respond_to?(:load)
|
52
|
+
MultiJson.dump object
|
53
|
+
else
|
54
|
+
MultiJson.encode object
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Given a string, returns a Ruby object.
|
59
|
+
def self.decode(object)
|
60
|
+
return unless object
|
61
|
+
|
62
|
+
begin
|
63
|
+
if MultiJson.respond_to?(:dump) && MultiJson.respond_to?(:load)
|
64
|
+
MultiJson.load object
|
65
|
+
else
|
66
|
+
MultiJson.decode object
|
67
|
+
end
|
68
|
+
rescue ::MultiJson::DecodeError => e
|
69
|
+
raise DecodeException, e.message, e.backtrace
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Given a word with dashes, returns a camel cased version of it.
|
74
|
+
#
|
75
|
+
# classify('job-name') # => 'JobName'
|
76
|
+
def classify(dashed_word)
|
77
|
+
dashed_word.split('-').each { |part| part[0] = part[0].chr.upcase }.join
|
78
|
+
end
|
79
|
+
|
80
|
+
# Tries to find a constant with the name specified in the argument string:
|
81
|
+
#
|
82
|
+
# constantize("Module") # => Module
|
83
|
+
# constantize("Test::Unit") # => Test::Unit
|
84
|
+
#
|
85
|
+
# The name is assumed to be the one of a top-level constant, no matter
|
86
|
+
# whether it starts with "::" or not. No lexical context is taken into
|
87
|
+
# account:
|
88
|
+
#
|
89
|
+
# C = 'outside'
|
90
|
+
# module M
|
91
|
+
# C = 'inside'
|
92
|
+
# C # => 'inside'
|
93
|
+
# constantize("C") # => 'outside', same as ::C
|
94
|
+
# end
|
95
|
+
#
|
96
|
+
# NameError is raised when the constant is unknown.
|
97
|
+
def constantize(camel_cased_word)
|
98
|
+
camel_cased_word = camel_cased_word.to_s
|
99
|
+
|
100
|
+
if camel_cased_word.include?('-')
|
101
|
+
camel_cased_word = classify(camel_cased_word)
|
102
|
+
end
|
103
|
+
|
104
|
+
names = camel_cased_word.split('::')
|
105
|
+
names.shift if names.empty? || names.first.empty?
|
106
|
+
|
107
|
+
constant = Object
|
108
|
+
names.each do |name|
|
109
|
+
args = Module.method(:const_get).arity != 1 ? [false] : []
|
110
|
+
|
111
|
+
if constant.const_defined?(name, *args)
|
112
|
+
constant = constant.const_get(name)
|
113
|
+
else
|
114
|
+
constant = constant.const_missing(name)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
constant
|
118
|
+
end
|
17
119
|
|
18
120
|
# Raise Resque::Job::DontPerform from a before_perform hook to
|
19
121
|
# abort the job.
|
@@ -166,6 +268,19 @@ module Resque
|
|
166
268
|
@payload_class ||= constantize(@payload['class'])
|
167
269
|
end
|
168
270
|
|
271
|
+
# Returns the payload class as a string without raising NameError
|
272
|
+
def payload_class_name
|
273
|
+
payload_class.to_s
|
274
|
+
rescue NameError
|
275
|
+
'No Name'
|
276
|
+
end
|
277
|
+
|
278
|
+
def has_payload_class?
|
279
|
+
payload_class != Object
|
280
|
+
rescue NameError
|
281
|
+
false
|
282
|
+
end
|
283
|
+
|
169
284
|
# Returns an array of args represented in this job's payload.
|
170
285
|
def args
|
171
286
|
@payload['args']
|
@@ -220,7 +335,9 @@ module Resque
|
|
220
335
|
def run_failure_hooks(exception)
|
221
336
|
begin
|
222
337
|
job_args = args || []
|
223
|
-
|
338
|
+
if has_payload_class?
|
339
|
+
failure_hooks.each { |hook| payload_class.send(hook, exception, *job_args) } unless @failure_hooks_ran
|
340
|
+
end
|
224
341
|
ensure
|
225
342
|
@failure_hooks_ran = true
|
226
343
|
end
|