backburner 1.7.0 → 1.9.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 +4 -4
- data/CHANGELOG.md +53 -4
- data/HOOKS.md +23 -14
- data/README.md +102 -23
- data/bin/backburner +1 -1
- data/lib/active_job/queue_adapters/backburner_adapter.rb +19 -5
- data/lib/backburner/cli.rb +1 -1
- data/lib/backburner/configuration.rb +7 -0
- data/lib/backburner/connection.rb +4 -2
- data/lib/backburner/enqueue_pool.rb +90 -0
- data/lib/backburner/helpers.rb +77 -22
- data/lib/backburner/job.rb +46 -7
- data/lib/backburner/logger.rb +9 -0
- data/lib/backburner/performable.rb +29 -4
- data/lib/backburner/queue.rb +37 -19
- data/lib/backburner/version.rb +1 -1
- data/lib/backburner/worker.rb +150 -25
- data/lib/backburner/workers/forking.rb +4 -2
- data/lib/backburner/workers/simple.rb +5 -0
- data/lib/backburner/workers/threading.rb +17 -7
- data/lib/backburner/workers/threads_on_fork.rb +59 -23
- data/lib/backburner.rb +7 -1
- metadata +40 -66
- data/.gitignore +0 -17
- data/.travis.yml +0 -29
- data/CONTRIBUTING.md +0 -37
- data/Gemfile +0 -4
- data/Rakefile +0 -17
- data/TODO +0 -4
- data/backburner.gemspec +0 -28
- data/circle.yml +0 -3
- data/examples/custom.rb +0 -25
- data/examples/demo.rb +0 -60
- data/examples/god.rb +0 -46
- data/examples/hooked.rb +0 -87
- data/examples/retried.rb +0 -31
- data/examples/simple.rb +0 -43
- data/examples/stress.rb +0 -31
- data/test/async_proxy_test.rb +0 -36
- data/test/back_burner_test.rb +0 -88
- data/test/connection_test.rb +0 -179
- data/test/fixtures/active_jobs.rb +0 -11
- data/test/fixtures/hooked.rb +0 -122
- data/test/fixtures/test_fork_jobs.rb +0 -72
- data/test/fixtures/test_forking_jobs.rb +0 -56
- data/test/fixtures/test_jobs.rb +0 -87
- data/test/fixtures/test_queue_settings.rb +0 -14
- data/test/helpers/templogger.rb +0 -22
- data/test/helpers_test.rb +0 -278
- data/test/hooks_test.rb +0 -112
- data/test/job_test.rb +0 -185
- data/test/logger_test.rb +0 -44
- data/test/performable_test.rb +0 -88
- data/test/queue_test.rb +0 -69
- data/test/test_helper.rb +0 -125
- data/test/worker_test.rb +0 -157
- data/test/workers/forking_worker_test.rb +0 -181
- data/test/workers/simple_worker_test.rb +0 -350
- data/test/workers/threading_worker_test.rb +0 -104
- data/test/workers/threads_on_fork_worker_test.rb +0 -484
data/lib/backburner/helpers.rb
CHANGED
|
@@ -11,7 +11,7 @@ module Backburner
|
|
|
11
11
|
|
|
12
12
|
base = File.expand_path(Dir.pwd) + '/'
|
|
13
13
|
e.backtrace.each do |t|
|
|
14
|
-
msg << " #{File.expand_path(t).gsub(
|
|
14
|
+
msg << " #{File.expand_path(t).gsub(base, '')}"
|
|
15
15
|
end if e.backtrace
|
|
16
16
|
|
|
17
17
|
msg.join("\n")
|
|
@@ -44,20 +44,13 @@ module Backburner
|
|
|
44
44
|
# constantize("Module") # => Module
|
|
45
45
|
# constantize("Test::Unit") # => Test::Unit
|
|
46
46
|
#
|
|
47
|
-
# NameError is raised when the constant is unknown.
|
|
47
|
+
# NameError is raised when the constant is unknown. Given a block, yields each module and the name
|
|
48
|
+
# of the constant it is about to look up in it, so a caller can tell which one failed.
|
|
48
49
|
def constantize(camel_cased_word)
|
|
49
|
-
camel_cased_word = camel_cased_word.to_s
|
|
50
|
-
|
|
51
|
-
if camel_cased_word.include?('-')
|
|
52
|
-
camel_cased_word = classify(camel_cased_word)
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
names = camel_cased_word.split('::')
|
|
56
|
-
names.shift if names.empty? || names.first.empty?
|
|
57
|
-
|
|
58
50
|
constant = Object
|
|
59
|
-
|
|
51
|
+
constant_names(camel_cased_word).each do |name|
|
|
60
52
|
args = Module.method(:const_get).arity != 1 ? [false] : []
|
|
53
|
+
yield constant, name if block_given?
|
|
61
54
|
|
|
62
55
|
if constant.const_defined?(name, *args)
|
|
63
56
|
constant = constant.const_get(name)
|
|
@@ -68,6 +61,23 @@ module Backburner
|
|
|
68
61
|
constant
|
|
69
62
|
end
|
|
70
63
|
|
|
64
|
+
# The names of the constants constantize looks up in turn
|
|
65
|
+
#
|
|
66
|
+
# @example
|
|
67
|
+
# constant_names("Test::Unit") # => ["Test", "Unit"]
|
|
68
|
+
#
|
|
69
|
+
def constant_names(camel_cased_word)
|
|
70
|
+
camel_cased_word = camel_cased_word.to_s
|
|
71
|
+
|
|
72
|
+
if camel_cased_word.include?('-')
|
|
73
|
+
camel_cased_word = classify(camel_cased_word)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
names = camel_cased_word.split('::')
|
|
77
|
+
names.shift if names.empty? || names.first.empty?
|
|
78
|
+
names
|
|
79
|
+
end
|
|
80
|
+
|
|
71
81
|
# Returns configuration options for backburner
|
|
72
82
|
#
|
|
73
83
|
# @example
|
|
@@ -85,7 +95,7 @@ module Backburner
|
|
|
85
95
|
# expand_tube_name(FooJob) # => <prefix>.foo-job
|
|
86
96
|
#
|
|
87
97
|
def expand_tube_name(tube)
|
|
88
|
-
prefix = queue_config.tube_namespace
|
|
98
|
+
prefix = queue_config.tube_namespace # nil or false mean no prefix; '' gives names that start with the separator, as in 1.7.0
|
|
89
99
|
separator = queue_config.namespace_separator
|
|
90
100
|
queue_name = if tube.is_a?(String)
|
|
91
101
|
tube
|
|
@@ -99,7 +109,29 @@ module Backburner
|
|
|
99
109
|
else # turn into a string
|
|
100
110
|
tube.to_s
|
|
101
111
|
end
|
|
102
|
-
|
|
112
|
+
tube_name = dasherize(queue_name)
|
|
113
|
+
tube_name = [separator.empty? ? prefix : prefix.gsub(/\.$/, ''), tube_name.gsub(namespace_pattern(prefix), '')].join(separator) if prefix
|
|
114
|
+
tube_name = tube_name.gsub(/#{Regexp::escape(separator)}+/, separator) unless separator.empty? # /+/ isn't a regexp
|
|
115
|
+
tube_name.split(':').first
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# What every tube name expand_tube_name gives starts with: the namespace and its separator ('' for a nil or false one)
|
|
119
|
+
#
|
|
120
|
+
# @example
|
|
121
|
+
# expanded_tube_prefix # => "<prefix>."
|
|
122
|
+
#
|
|
123
|
+
def expanded_tube_prefix
|
|
124
|
+
expand_tube_name('').to_s
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# The namespace as the pattern expand_tube_name strips from the start of a queue name.
|
|
128
|
+
# ceiling: a namespace that is a valid regexp is still matched as one ("app.prod" also strips "app-prod"), because
|
|
129
|
+
# matching it literally would move the jobs of the queue names it matches to other tubes; one that isn't ("app(")
|
|
130
|
+
# used to fail every enqueue and is matched literally.
|
|
131
|
+
def namespace_pattern(prefix)
|
|
132
|
+
Regexp.new("^#{prefix}")
|
|
133
|
+
rescue RegexpError
|
|
134
|
+
Regexp.new("^#{Regexp.escape(prefix)}")
|
|
103
135
|
end
|
|
104
136
|
|
|
105
137
|
# Resolves job priority based on the value given. Can be integer, a class or nothing
|
|
@@ -110,21 +142,31 @@ module Backburner
|
|
|
110
142
|
# resolve_priority(nil) => <default priority>
|
|
111
143
|
#
|
|
112
144
|
def resolve_priority(pri)
|
|
145
|
+
priority = resolve_priority_value(pri)
|
|
146
|
+
return priority if priority
|
|
147
|
+
default = Backburner.configuration.default_priority # can be a label too
|
|
148
|
+
resolve_priority_value(default) || default # left as configured if it isn't a known label
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# Follows a job class's queue_priority and priority labels to a number; nil for nothing,
|
|
152
|
+
# an unknown label or a cycle of labels
|
|
153
|
+
def resolve_priority_value(pri, seen_labels = [])
|
|
113
154
|
if pri.respond_to?(:queue_priority)
|
|
114
|
-
|
|
155
|
+
resolve_priority_value(pri.queue_priority, seen_labels)
|
|
115
156
|
elsif pri.is_a?(String) || pri.is_a?(Symbol) # named priority
|
|
116
|
-
|
|
157
|
+
label = pri.to_sym
|
|
158
|
+
resolve_priority_value(Backburner.configuration.priority_labels[label], seen_labels + [label]) unless seen_labels.include?(label)
|
|
117
159
|
elsif pri.is_a?(Integer) # numerical
|
|
118
160
|
pri
|
|
119
|
-
else # default
|
|
120
|
-
Backburner.configuration.default_priority
|
|
121
161
|
end
|
|
122
162
|
end
|
|
123
163
|
|
|
124
|
-
# Resolves job respond timeout based on the value given. Can be
|
|
164
|
+
# Resolves job respond timeout based on the value given, rounded up to whole seconds. Can be a number,
|
|
165
|
+
# a class or nothing
|
|
125
166
|
#
|
|
126
167
|
# @example
|
|
127
168
|
# resolve_respond_timeout(1000) => 1000
|
|
169
|
+
# resolve_respond_timeout(1.5) => 2
|
|
128
170
|
# resolve_respond_timeout(FooBar) => <queue respond_timeout>
|
|
129
171
|
# resolve_respond_timeout(nil) => <default respond_timeout>
|
|
130
172
|
#
|
|
@@ -133,8 +175,11 @@ module Backburner
|
|
|
133
175
|
resolve_respond_timeout(ttr.queue_respond_timeout)
|
|
134
176
|
elsif ttr.is_a?(Integer) # numerical
|
|
135
177
|
ttr
|
|
178
|
+
elsif ttr.is_a?(Numeric) && ttr.finite? # fractional
|
|
179
|
+
whole_seconds(ttr)
|
|
136
180
|
else # default
|
|
137
|
-
Backburner.configuration.respond_timeout
|
|
181
|
+
ttr = Backburner.configuration.respond_timeout
|
|
182
|
+
!ttr.is_a?(Integer) && ttr.is_a?(Numeric) && ttr.finite? ? whole_seconds(ttr) : ttr
|
|
138
183
|
end
|
|
139
184
|
end
|
|
140
185
|
|
|
@@ -155,7 +200,7 @@ module Backburner
|
|
|
155
200
|
end
|
|
156
201
|
end
|
|
157
202
|
|
|
158
|
-
# Resolves retry delay based on the value given. Can be
|
|
203
|
+
# Resolves retry delay based on the value given. Can be a number, a class or nothing
|
|
159
204
|
#
|
|
160
205
|
# @example
|
|
161
206
|
# resolve_retry_delay(5) => 5
|
|
@@ -165,7 +210,7 @@ module Backburner
|
|
|
165
210
|
def resolve_retry_delay(delay)
|
|
166
211
|
if delay.respond_to?(:queue_retry_delay)
|
|
167
212
|
resolve_retry_delay(delay.queue_retry_delay)
|
|
168
|
-
elsif delay.is_a?(
|
|
213
|
+
elsif delay.is_a?(Numeric) && delay.finite? # numerical (the worker rounds the delay it computes from it up)
|
|
169
214
|
delay
|
|
170
215
|
else # default
|
|
171
216
|
Backburner.configuration.retry_delay
|
|
@@ -189,5 +234,15 @@ module Backburner
|
|
|
189
234
|
end
|
|
190
235
|
end
|
|
191
236
|
|
|
237
|
+
# Rounds a delay up to the whole seconds beanstalkd takes, so a job is never ready early
|
|
238
|
+
#
|
|
239
|
+
# @example
|
|
240
|
+
# whole_seconds(1.5) => 2
|
|
241
|
+
# whole_seconds(nil) => 0
|
|
242
|
+
#
|
|
243
|
+
def whole_seconds(delay)
|
|
244
|
+
[0, delay.to_f.ceil].max
|
|
245
|
+
end
|
|
246
|
+
|
|
192
247
|
end # Helpers
|
|
193
248
|
end # Backburner
|
data/lib/backburner/job.rb
CHANGED
|
@@ -45,12 +45,15 @@ module Backburner
|
|
|
45
45
|
def process
|
|
46
46
|
# Invoke before hook and stop if false
|
|
47
47
|
res = @hooks.invoke_hook_events(job_name, :before_perform, *args)
|
|
48
|
-
|
|
48
|
+
unless res
|
|
49
|
+
task.delete # aborted: don't leave it reserved, or beanstalkd hands it out again after its TTR
|
|
50
|
+
return false
|
|
51
|
+
end
|
|
49
52
|
# Execute the job
|
|
50
53
|
@hooks.around_hook_events(job_name, :around_perform, *args) do
|
|
51
|
-
# We subtract one to ensure we timeout before beanstalkd does, except if
|
|
52
|
-
#
|
|
53
|
-
#
|
|
54
|
+
# We subtract one to ensure we timeout before beanstalkd does, except if
|
|
55
|
+
# ttr == 1 (beanstalkd's minimum: it stores a ttr of 0 as 1), so that we
|
|
56
|
+
# don't accidentally set it to never time out.
|
|
54
57
|
# NB: A ttr of 1 will likely result in race conditions between
|
|
55
58
|
# Backburner and beanstalkd and should probably be avoided
|
|
56
59
|
timeout_job_after(task.ttr > 1 ? task.ttr - 1 : task.ttr) { job_class.perform(*args) }
|
|
@@ -80,10 +83,16 @@ module Backburner
|
|
|
80
83
|
#
|
|
81
84
|
def job_class
|
|
82
85
|
handler = try_job_class
|
|
83
|
-
raise(JobNotFound,
|
|
86
|
+
raise(JobNotFound, @job_class_error ? "#{name} (#{@job_class_error.class}: #{@job_class_error.message.to_s.lines.first.to_s.chomp})" : name) unless handler
|
|
84
87
|
handler
|
|
85
88
|
end
|
|
86
89
|
|
|
90
|
+
# Whether the last lookup of the job's class found it missing (not defined, or an autoload whose
|
|
91
|
+
# file isn't there) rather than failing to load it (its file raised, or required a missing gem)
|
|
92
|
+
def job_class_missing?
|
|
93
|
+
!!@job_class_missing
|
|
94
|
+
end
|
|
95
|
+
|
|
87
96
|
protected
|
|
88
97
|
|
|
89
98
|
# Attempts to return a constantized job name, otherwise reverts to the name string
|
|
@@ -96,11 +105,41 @@ module Backburner
|
|
|
96
105
|
end
|
|
97
106
|
|
|
98
107
|
def try_job_class
|
|
99
|
-
|
|
100
|
-
|
|
108
|
+
@job_class_error = nil
|
|
109
|
+
@job_class_missing = false
|
|
110
|
+
scope = segment = autoload_path = nil
|
|
111
|
+
invalid_name = !constant_names(self.name).all? { |name| constant_name?(name) }
|
|
112
|
+
constantize(self.name) do |mod, name|
|
|
113
|
+
scope, segment = mod, name
|
|
114
|
+
autoload_path = mod.autoload?(name) rescue nil # a module, or the value of a constant that isn't one
|
|
115
|
+
end
|
|
116
|
+
rescue StandardError, ScriptError => e # its file may raise anything; an autoloader may raise LoadError for a file that isn't there
|
|
117
|
+
@job_class_error = e
|
|
118
|
+
@job_class_missing = !invalid_name && missing_constant_error?(e, scope, segment, autoload_path)
|
|
101
119
|
nil
|
|
102
120
|
end
|
|
103
121
|
|
|
122
|
+
# Whether a name can be a constant's: one that can't ("not a class", "123") will never be found
|
|
123
|
+
def constant_name?(name)
|
|
124
|
+
Module.new.const_defined?(name, false) # raises NameError for one that can't
|
|
125
|
+
true
|
|
126
|
+
rescue NameError
|
|
127
|
+
false
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# Whether an error raised while looking up `segment` in `scope` says that constant is missing,
|
|
131
|
+
# rather than coming from inside the file that defines it (a NameError for another constant, or for
|
|
132
|
+
# one of the same name in another module, a NoMethodError, a require of a missing gem, any other
|
|
133
|
+
# error or a syntax error)
|
|
134
|
+
def missing_constant_error?(e, scope, segment, autoload_path)
|
|
135
|
+
case e
|
|
136
|
+
when NoMethodError then false
|
|
137
|
+
when NameError then e.name.to_s == segment.to_s && (e.receiver.equal?(scope) rescue true) # no receiver: by name only
|
|
138
|
+
when LoadError then e.path.nil? || e.path == autoload_path
|
|
139
|
+
else false
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
104
143
|
# Timeout job within specified block after given time.
|
|
105
144
|
#
|
|
106
145
|
# @example
|
data/lib/backburner/logger.rb
CHANGED
|
@@ -45,6 +45,15 @@ module Backburner
|
|
|
45
45
|
logger ? logger.error(msg) : $stderr.puts(msg)
|
|
46
46
|
end
|
|
47
47
|
|
|
48
|
+
# Print a warning to stderr
|
|
49
|
+
#
|
|
50
|
+
# @example
|
|
51
|
+
# log_warn("Task released!")
|
|
52
|
+
#
|
|
53
|
+
def log_warn(msg)
|
|
54
|
+
logger ? (logger.respond_to?(:warn) ? logger.warn(msg) : logger.error(msg)) : $stderr.puts(msg)
|
|
55
|
+
end
|
|
56
|
+
|
|
48
57
|
# Return logger if specified
|
|
49
58
|
def logger
|
|
50
59
|
Backburner.configuration.logger
|
|
@@ -28,14 +28,16 @@ module Backburner
|
|
|
28
28
|
Backburner::AsyncProxy.new(self, nil, opts)
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
-
# Defines perform method for job processing
|
|
31
|
+
# Defines perform method for job processing. It calls a method the app defines on the class,
|
|
32
|
+
# its superclasses or the modules they include, and raises NoMethodError for any other.
|
|
32
33
|
# @example
|
|
33
34
|
# perform(55, :do_something, "foo", "bar")
|
|
34
35
|
def perform(id, method, *args)
|
|
35
36
|
if id # instance
|
|
36
|
-
find(id)
|
|
37
|
+
record = find(id)
|
|
38
|
+
Backburner::Performable.perform_job_method(record, record.class, Object, method, args)
|
|
37
39
|
else # class method
|
|
38
|
-
|
|
40
|
+
Backburner::Performable.perform_job_method(self, singleton_class, Object.singleton_class, method, args)
|
|
39
41
|
end
|
|
40
42
|
end # perform
|
|
41
43
|
|
|
@@ -79,7 +81,7 @@ module Backburner
|
|
|
79
81
|
with_async_name = :"#{aliased_method}_with_async#{punctuation}"
|
|
80
82
|
without_async_name = :"#{aliased_method}_without_async#{punctuation}"
|
|
81
83
|
|
|
82
|
-
klass.send(:include, Performable) unless included_modules.include?(Performable)
|
|
84
|
+
klass.send(:include, Performable) unless klass.included_modules.include?(Performable)
|
|
83
85
|
klass_eval_scope.class_eval do
|
|
84
86
|
define_method with_async_name do |*args|
|
|
85
87
|
async(opts).__send__ without_async_name, *args
|
|
@@ -90,6 +92,29 @@ module Backburner
|
|
|
90
92
|
end
|
|
91
93
|
private_class_method :_handle_asynchronously
|
|
92
94
|
|
|
95
|
+
# Calls a job's method on `receiver`. It raises NoMethodError when the method isn't one the app
|
|
96
|
+
# defined: one that `methods_of` (the receiver's class, or the singleton class for a class method)
|
|
97
|
+
# gets from `core` (Object, or Object's singleton class for a class method) or the modules mixed
|
|
98
|
+
# into it, from Backburner's own modules, or Ruby's method_missing hook. A method with the same name
|
|
99
|
+
# as one of core's must be the app's own definition: one that method_missing would handle, or one
|
|
100
|
+
# from Delegator's copy of Kernel (the module delegate.rb aliases __raise__ in), is refused too.
|
|
101
|
+
def self.perform_job_method(receiver, methods_of, core, method, args)
|
|
102
|
+
owner = begin
|
|
103
|
+
methods_of.instance_method(method).owner
|
|
104
|
+
rescue NameError
|
|
105
|
+
nil
|
|
106
|
+
end
|
|
107
|
+
refused = if owner && (core.ancestors.include?(owner) || [InstanceMethods, ClassMethods, Backburner::Queue::ClassMethods].include?(owner))
|
|
108
|
+
true
|
|
109
|
+
elsif core.method_defined?(method) || core.private_method_defined?(method)
|
|
110
|
+
owner.nil? || method.to_sym == :method_missing || (defined?(::Delegator) && owner.equal?(::Delegator.instance_method(:__raise__).owner))
|
|
111
|
+
end
|
|
112
|
+
if refused
|
|
113
|
+
kind = methods_of.singleton_class? ? "class method" : "method"
|
|
114
|
+
raise NoMethodError.new("undefined job #{kind} '#{method}' for #{methods_of.singleton_class? ? receiver : methods_of}", method.to_sym, receiver: receiver)
|
|
115
|
+
end
|
|
116
|
+
receiver.__send__(method, *args)
|
|
117
|
+
end
|
|
93
118
|
|
|
94
119
|
end # Performable
|
|
95
120
|
end # Backburner
|
data/lib/backburner/queue.rb
CHANGED
|
@@ -1,17 +1,14 @@
|
|
|
1
1
|
module Backburner
|
|
2
2
|
module Queue
|
|
3
3
|
def self.included(base)
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
base.instance_variable_set(:@queue_jobs_limit, nil)
|
|
11
|
-
base.instance_variable_set(:@queue_garbage_limit, nil)
|
|
12
|
-
base.instance_variable_set(:@queue_retry_limit, nil)
|
|
4
|
+
# Initialize the settings, but keep any already set: including Queue again (as including
|
|
5
|
+
# Performable does) must not reset them
|
|
6
|
+
[:@queue_name, :@queue_priority, :@queue_respond_timeout, :@queue_max_job_retries, :@queue_retry_delay,
|
|
7
|
+
:@queue_retry_delay_proc, :@queue_jobs_limit, :@queue_garbage_limit, :@queue_retry_limit].each do |setting|
|
|
8
|
+
base.instance_variable_set(setting, nil) unless base.instance_variable_defined?(setting)
|
|
9
|
+
end
|
|
13
10
|
base.extend ClassMethods
|
|
14
|
-
Backburner::Worker.known_queue_classes << base
|
|
11
|
+
Backburner::Worker.known_queue_classes << base unless Backburner::Worker.known_queue_classes.include?(base)
|
|
15
12
|
end
|
|
16
13
|
|
|
17
14
|
module ClassMethods
|
|
@@ -25,7 +22,8 @@ module Backburner
|
|
|
25
22
|
if name
|
|
26
23
|
@queue_name = name
|
|
27
24
|
else # accessor
|
|
28
|
-
|
|
25
|
+
queue_name = inherited_queue_setting(:@queue_name)
|
|
26
|
+
(queue_name.is_a?(Proc) ? queue_name.call(self) : queue_name) || Backburner.configuration.primary_queue
|
|
29
27
|
end
|
|
30
28
|
end
|
|
31
29
|
|
|
@@ -39,7 +37,7 @@ module Backburner
|
|
|
39
37
|
if pri
|
|
40
38
|
@queue_priority = pri
|
|
41
39
|
else # accessor
|
|
42
|
-
|
|
40
|
+
inherited_queue_setting(:@queue_priority)
|
|
43
41
|
end
|
|
44
42
|
end
|
|
45
43
|
|
|
@@ -53,7 +51,7 @@ module Backburner
|
|
|
53
51
|
if ttr
|
|
54
52
|
@queue_respond_timeout = ttr
|
|
55
53
|
else # accessor
|
|
56
|
-
|
|
54
|
+
inherited_queue_setting(:@queue_respond_timeout)
|
|
57
55
|
end
|
|
58
56
|
end
|
|
59
57
|
|
|
@@ -67,7 +65,7 @@ module Backburner
|
|
|
67
65
|
if delay
|
|
68
66
|
@queue_max_job_retries = delay
|
|
69
67
|
else # accessor
|
|
70
|
-
|
|
68
|
+
inherited_queue_setting(:@queue_max_job_retries)
|
|
71
69
|
end
|
|
72
70
|
end
|
|
73
71
|
|
|
@@ -81,7 +79,7 @@ module Backburner
|
|
|
81
79
|
if delay
|
|
82
80
|
@queue_retry_delay = delay
|
|
83
81
|
else # accessor
|
|
84
|
-
|
|
82
|
+
inherited_queue_setting(:@queue_retry_delay)
|
|
85
83
|
end
|
|
86
84
|
end
|
|
87
85
|
|
|
@@ -95,7 +93,7 @@ module Backburner
|
|
|
95
93
|
if proc
|
|
96
94
|
@queue_retry_delay_proc = proc
|
|
97
95
|
else # accessor
|
|
98
|
-
|
|
96
|
+
inherited_queue_setting(:@queue_retry_delay_proc)
|
|
99
97
|
end
|
|
100
98
|
end
|
|
101
99
|
|
|
@@ -109,7 +107,7 @@ module Backburner
|
|
|
109
107
|
if limit
|
|
110
108
|
@queue_jobs_limit = limit
|
|
111
109
|
else #accessor
|
|
112
|
-
|
|
110
|
+
inherited_queue_setting(:@queue_jobs_limit)
|
|
113
111
|
end
|
|
114
112
|
end
|
|
115
113
|
|
|
@@ -123,7 +121,7 @@ module Backburner
|
|
|
123
121
|
if limit
|
|
124
122
|
@queue_garbage_limit = limit
|
|
125
123
|
else #accessor
|
|
126
|
-
|
|
124
|
+
inherited_queue_setting(:@queue_garbage_limit)
|
|
127
125
|
end
|
|
128
126
|
end
|
|
129
127
|
|
|
@@ -137,8 +135,28 @@ module Backburner
|
|
|
137
135
|
if limit
|
|
138
136
|
@queue_retry_limit = limit
|
|
139
137
|
else #accessor
|
|
140
|
-
|
|
138
|
+
inherited_queue_setting(:@queue_retry_limit)
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
private
|
|
143
|
+
|
|
144
|
+
# Registers subclasses as known queues too (they inherit the queue settings)
|
|
145
|
+
def inherited(subclass)
|
|
146
|
+
super
|
|
147
|
+
Backburner::Worker.known_queue_classes << subclass unless Backburner::Worker.known_queue_classes.include?(subclass)
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# Returns the setting from this class or else from the closest superclass that has it,
|
|
151
|
+
# so a subclass shares its parent's queue settings unless it sets its own
|
|
152
|
+
def inherited_queue_setting(ivar)
|
|
153
|
+
klass = self
|
|
154
|
+
while klass.is_a?(ClassMethods)
|
|
155
|
+
value = klass.instance_variable_get(ivar) if klass.instance_variable_defined?(ivar)
|
|
156
|
+
return value unless value.nil?
|
|
157
|
+
klass = klass.respond_to?(:superclass) ? klass.superclass : nil
|
|
141
158
|
end
|
|
159
|
+
nil
|
|
142
160
|
end
|
|
143
161
|
end # ClassMethods
|
|
144
162
|
end # Queue
|
data/lib/backburner/version.rb
CHANGED