backburner-allq 1.0.35 → 1.0.38
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/deploy.sh +1 -1
- data/lib/backburner/allq_wrapper.rb +18 -21
- data/lib/backburner/job.rb +5 -0
- data/lib/backburner/version.rb +1 -1
- data/lib/backburner/worker.rb +42 -34
- data/test/performable_test.rb +12 -12
- data/test/test_helper.rb +2 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1d44569a854f2a26375e77a62b485851cc1970bd7bacce5948178c65e17a1f27
|
4
|
+
data.tar.gz: 29d4a2408a0d7b77c6236a2fd716a07c9ddad32e1566d5d5575c99d557fcb7bf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9ea4a8b0da3978fe8567ecf7edbb4157246ad88da2acf9352038627e665f2240d877511e6f49f3775d42a54d61617c79dbbee2ccb71413a76797f1c77b01218d
|
7
|
+
data.tar.gz: 9e2be902d44f1600e86941c714c8bb09e2e902c636cba0cc34fd26a2fb901e79006e48df357877a3c3cc248966090561b37d4b10d5c6d0f207d5b7ab3be4e0e5
|
data/deploy.sh
CHANGED
@@ -42,13 +42,17 @@ module Backburner
|
|
42
42
|
# Release count
|
43
43
|
attr_accessor :releases
|
44
44
|
|
45
|
-
|
45
|
+
# Release count
|
46
|
+
attr_accessor :special
|
47
|
+
|
48
|
+
def initialize(wrapper, job_response)
|
46
49
|
@client = wrapper
|
47
|
-
@id =
|
48
|
-
@body =
|
49
|
-
@expireds =
|
50
|
-
@releases =
|
51
|
-
@tube =
|
50
|
+
@id = job_response.id
|
51
|
+
@body = job_response.body
|
52
|
+
@expireds = job_response.expireds
|
53
|
+
@releases = job_response.releases
|
54
|
+
@tube = job_response.tube.to_s
|
55
|
+
@special = job_response.special.to_s if job_response.special
|
52
56
|
end
|
53
57
|
|
54
58
|
def done
|
@@ -93,12 +97,6 @@ module Backburner
|
|
93
97
|
@recent_times = []
|
94
98
|
end
|
95
99
|
|
96
|
-
def speed
|
97
|
-
return @recent_times.sum(0.0) / @recent_times.size if @recent_times.size > 0
|
98
|
-
|
99
|
-
0
|
100
|
-
end
|
101
|
-
|
102
100
|
def touch(job)
|
103
101
|
@client.touch_put(job.id)
|
104
102
|
end
|
@@ -167,12 +165,6 @@ module Backburner
|
|
167
165
|
app_priority > 10 ? 5 : app_priority
|
168
166
|
end
|
169
167
|
|
170
|
-
def log_result(job_result)
|
171
|
-
puts("ALLQ-HTTP-JOB-ID=#{job_result.job_id}")
|
172
|
-
rescue StandardError => e
|
173
|
-
puts(e)
|
174
|
-
end
|
175
|
-
|
176
168
|
def build_new_job(body, options)
|
177
169
|
adjusted_priority = map_priority(options[:pri] || 5)
|
178
170
|
|
@@ -195,7 +187,6 @@ module Backburner
|
|
195
187
|
ttl = options[:ttl] || options[:ttr] || DEFAULT_TIMEOUT
|
196
188
|
tube_name = options[:tube_name] || 'default'
|
197
189
|
delay = options[:delay] || 0
|
198
|
-
parent_id = options[:parent_id]
|
199
190
|
limit = options[:limit]
|
200
191
|
timeout = options[:timeout] || 3_600
|
201
192
|
run_on_timeout = options[:run_on_timeout] || false
|
@@ -254,15 +245,21 @@ module Backburner
|
|
254
245
|
raw_stats = @admin.stats_get
|
255
246
|
final_stats = {}
|
256
247
|
|
257
|
-
raw_stats.
|
248
|
+
raw_stats.each_with_index do |agg, i|
|
258
249
|
agg.stats.each do |tube_ref|
|
259
250
|
name = tube_ref.tube
|
260
|
-
final_stats[name] = {} unless final_stats[name]
|
251
|
+
final_stats[name] = {'avg' => 0, 'tps' => 0} unless final_stats[name]
|
261
252
|
final_stats[name]['ready'] = final_stats[name]['ready'].to_i + tube_ref.ready.to_i
|
262
253
|
final_stats[name]['reserved'] = final_stats[name]['reserved'].to_i + tube_ref.reserved.to_i
|
263
254
|
final_stats[name]['delayed'] = final_stats[name]['delayed'].to_i + tube_ref.delayed.to_i
|
264
255
|
final_stats[name]['buried'] = final_stats[name]['buried'].to_i + tube_ref.buried.to_i
|
265
256
|
final_stats[name]['parents'] = final_stats[name]['parents'].to_i + tube_ref.parents.to_i
|
257
|
+
|
258
|
+
|
259
|
+
# Fancy math to calculate averages on the fly
|
260
|
+
# https://math.stackexchange.com/questions/106313/regular-average-calculated-accumulatively
|
261
|
+
final_stats[name]['avg'] += (tube_ref.avg.to_f - final_stats[name]['avg'].to_f)/(i+1).to_f
|
262
|
+
final_stats[name]['tps'] += (tube_ref.tps.to_f - final_stats[name]['tps'].to_f)/(i+1).to_f
|
266
263
|
end
|
267
264
|
end
|
268
265
|
final_stats
|
data/lib/backburner/job.rb
CHANGED
@@ -26,6 +26,11 @@ module Backburner
|
|
26
26
|
@name = body["class"] || body[:class]
|
27
27
|
@args = body["args"] || body[:args]
|
28
28
|
@ttr = body["ttr"] || body[:ttr]
|
29
|
+
if @task.special
|
30
|
+
@args ||= {}
|
31
|
+
@args["special"] = @task.special.to_s
|
32
|
+
end
|
33
|
+
|
29
34
|
rescue => ex # Job was not valid format
|
30
35
|
# self.bury
|
31
36
|
# raise JobFormatInvalid, "Job body could not be parsed: #{ex.inspect}"
|
data/lib/backburner/version.rb
CHANGED
data/lib/backburner/worker.rb
CHANGED
@@ -13,7 +13,10 @@ module Backburner
|
|
13
13
|
# List of known_queue_classes
|
14
14
|
class << self
|
15
15
|
attr_writer :known_queue_classes
|
16
|
-
|
16
|
+
|
17
|
+
def known_queue_classes
|
18
|
+
@known_queue_classes ||= []
|
19
|
+
end
|
17
20
|
end
|
18
21
|
|
19
22
|
# Enqueues a job to be processed later by a worker.
|
@@ -23,8 +26,13 @@ module Backburner
|
|
23
26
|
# @example
|
24
27
|
# Backburner::Worker.enqueue NewsletterSender, [self.id, user.id], :ttr => 1000
|
25
28
|
#
|
26
|
-
def self.enqueue(job_class, args=[], opts={})
|
27
|
-
|
29
|
+
def self.enqueue(job_class, args = [], opts = {})
|
30
|
+
# Invoke Procs if they are sent
|
31
|
+
opts.each_key do |k|
|
32
|
+
opts[k] = opts[k].call job_class, args if opts[k].instance_of?(Proc)
|
33
|
+
end
|
34
|
+
|
35
|
+
opts[:shard_key] = opts[:shard_key].nil? ? 'X' : opts[:shard_key].to_s
|
28
36
|
pri = resolve_priority(opts[:pri] || job_class)
|
29
37
|
delay = [0, opts[:delay].to_i].max
|
30
38
|
ttr = resolve_respond_timeout(opts[:ttr] || job_class)
|
@@ -32,8 +40,8 @@ module Backburner
|
|
32
40
|
|
33
41
|
return nil unless res # stop if hook is false
|
34
42
|
|
35
|
-
data = { :
|
36
|
-
queue = opts[:queue] && (
|
43
|
+
data = { class: job_class.name, args: args, ttr: ttr }
|
44
|
+
queue = opts[:queue] && (opts[:queue].is_a?(Proc) ? opts[:queue].call(job_class) : opts[:queue])
|
37
45
|
|
38
46
|
begin
|
39
47
|
response = nil
|
@@ -62,12 +70,10 @@ module Backburner
|
|
62
70
|
# @example
|
63
71
|
# Backburner::Worker.start(["foo.tube.name"])
|
64
72
|
#
|
65
|
-
def self.start(tube_names=nil)
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
# do nothing
|
70
|
-
end
|
73
|
+
def self.start(tube_names = nil)
|
74
|
+
new(tube_names).start
|
75
|
+
rescue SystemExit
|
76
|
+
# do nothing
|
71
77
|
end
|
72
78
|
|
73
79
|
# List of tube names to be watched and processed
|
@@ -77,9 +83,9 @@ module Backburner
|
|
77
83
|
#
|
78
84
|
# @example
|
79
85
|
# Worker.new(['test.job'])
|
80
|
-
def initialize(tube_names=nil)
|
86
|
+
def initialize(tube_names = nil)
|
81
87
|
@connection = new_connection
|
82
|
-
@tube_names =
|
88
|
+
@tube_names = process_tube_names(tube_names)
|
83
89
|
register_signal_handlers!
|
84
90
|
end
|
85
91
|
|
@@ -135,31 +141,30 @@ module Backburner
|
|
135
141
|
# @raise [Beaneater::NotConnected] If beanstalk fails to connect multiple times.
|
136
142
|
def work_one_job(conn = connection, tube_name = nil)
|
137
143
|
if tube_name.nil?
|
138
|
-
|
139
|
-
tube_name = @tube_names.sample
|
144
|
+
log_error 'Sampling tube, this is bad practice for Allq'
|
145
|
+
tube_name = @tube_names.sample
|
140
146
|
end
|
141
|
-
|
147
|
+
|
142
148
|
begin
|
143
149
|
job = reserve_job(conn, tube_name)
|
144
150
|
rescue Exception => e
|
145
|
-
|
146
|
-
|
147
|
-
sleep(rand*3)
|
151
|
+
log_error "Exception: #{e.full_message}"
|
152
|
+
sleep(rand * 3)
|
148
153
|
return
|
149
154
|
end
|
150
155
|
|
151
156
|
if job && job.body
|
152
157
|
begin
|
153
|
-
|
158
|
+
log_job_begin(job.name, job.args)
|
154
159
|
job.process
|
155
|
-
|
160
|
+
log_job_end(job.name)
|
156
161
|
rescue Backburner::Job::JobFormatInvalid => e
|
157
|
-
|
158
|
-
rescue => e # Error occurred processing job
|
159
|
-
|
162
|
+
log_error exception_message(e)
|
163
|
+
rescue StandardError => e # Error occurred processing job
|
164
|
+
log_error exception_message(e) unless e.is_a?(Backburner::Job::RetryJob)
|
160
165
|
|
161
166
|
unless job
|
162
|
-
|
167
|
+
log_error 'Error occurred before we were able to assign a job. Giving up without retrying!'
|
163
168
|
return
|
164
169
|
end
|
165
170
|
|
@@ -167,26 +172,29 @@ module Backburner
|
|
167
172
|
# gone down between the time we reserved / processed the job and here.
|
168
173
|
num_retries = job.releases
|
169
174
|
max_job_retries = resolve_max_job_retries(job.job_class)
|
170
|
-
retry_status = "failed: attempt #{num_retries+1} of #{max_job_retries+1}"
|
175
|
+
retry_status = "failed: attempt #{num_retries + 1} of #{max_job_retries + 1}"
|
171
176
|
retry_delay = resolve_retry_delay(job.job_class)
|
172
|
-
delay =
|
173
|
-
|
177
|
+
delay = begin
|
178
|
+
resolve_retry_delay_proc(job.job_class).call(retry_delay, num_retries)
|
179
|
+
rescue StandardError
|
180
|
+
retry_delay
|
181
|
+
end
|
182
|
+
|
174
183
|
if num_retries + 1 > max_job_retries
|
175
184
|
job.bury
|
176
185
|
else
|
177
186
|
job.release(delay)
|
178
187
|
end
|
179
|
-
|
188
|
+
log_job_end(job.name, "#{retry_status}, retrying in #{delay}s") if job_started_at
|
180
189
|
|
181
190
|
handle_error(e, job.name, job.args, job)
|
182
191
|
end
|
183
192
|
else
|
184
|
-
sleep(rand*3)
|
193
|
+
sleep(rand * 3)
|
185
194
|
end
|
186
195
|
job
|
187
196
|
end
|
188
197
|
|
189
|
-
|
190
198
|
protected
|
191
199
|
|
192
200
|
# Return a new connection instance
|
@@ -195,9 +203,10 @@ module Backburner
|
|
195
203
|
end
|
196
204
|
|
197
205
|
# Reserve a job from the watched queues
|
198
|
-
def reserve_job(conn, tube_name,
|
206
|
+
def reserve_job(conn, tube_name, _reserve_timeout = Backburner.configuration.reserve_timeout)
|
199
207
|
job = conn.get(tube_name)
|
200
208
|
return nil if job.nil? || job.body == nil?
|
209
|
+
|
201
210
|
Backburner::Job.new(job)
|
202
211
|
end
|
203
212
|
|
@@ -205,11 +214,10 @@ module Backburner
|
|
205
214
|
# Filtered for tubes that match the known prefix
|
206
215
|
def all_existing_queues
|
207
216
|
known_queues = Backburner::Worker.known_queue_classes.map(&:queue)
|
208
|
-
existing_tubes =
|
217
|
+
existing_tubes = connection.tubes.all.map(&:name).select { |tube| tube =~ /^#{queue_config.tube_namespace}/ }
|
209
218
|
existing_tubes + known_queues + [queue_config.primary_queue]
|
210
219
|
end
|
211
220
|
|
212
|
-
|
213
221
|
# Handles an error according to custom definition
|
214
222
|
# Used when processing a job that errors out
|
215
223
|
def handle_error(e, name, args, job)
|
data/test/performable_test.rb
CHANGED
@@ -29,15 +29,15 @@ describe "Backburner::Performable module" do
|
|
29
29
|
|
30
30
|
describe "for async instance method" do
|
31
31
|
it "should invoke worker enqueue" do
|
32
|
-
Backburner::Worker.expects(:enqueue).with(PerformableTestObj, [56, :foo, true, false], has_entries(:pri => 5000, :queue => "foo"))
|
33
|
-
PerformableTestObj.new.async(:pri => 5000, :queue => "foo").foo(true, false)
|
32
|
+
Backburner::Worker.expects(:enqueue).with(PerformableTestObj, [56, :foo, true, false], has_entries(:pri => 5000, :queue => "foo", :shard_key => "abc"))
|
33
|
+
PerformableTestObj.new.async(:pri => 5000, :queue => "foo", :shard_key => "abc").foo(true, false)
|
34
34
|
end
|
35
35
|
end # async instance
|
36
36
|
|
37
37
|
describe "for async class method" do
|
38
38
|
it "should invoke worker enqueue" do
|
39
|
-
Backburner::Worker.expects(:enqueue).with(PerformableTestObj, [nil, :bar, true, false], has_entries(:pri => 5000, :queue => "foo"))
|
40
|
-
PerformableTestObj.async(:pri => 5000, :queue => "foo").bar(true, false)
|
39
|
+
Backburner::Worker.expects(:enqueue).with(PerformableTestObj, [nil, :bar, true, false], has_entries(:pri => 5000, :queue => "foo", :shard_key => "abc"))
|
40
|
+
PerformableTestObj.async(:pri => 5000, :queue => "foo", :shard_key => "abc").bar(true, false)
|
41
41
|
end
|
42
42
|
end # async class
|
43
43
|
|
@@ -53,16 +53,16 @@ describe "Backburner::Performable module" do
|
|
53
53
|
|
54
54
|
describe "for handle_asynchronously class method" do
|
55
55
|
it "should automagically asynchronously proxy calls to the method" do
|
56
|
-
Backburner::Performable.handle_asynchronously(AutomagicTestObj, :qux, :pri => 5000, :queue => "qux")
|
56
|
+
Backburner::Performable.handle_asynchronously(AutomagicTestObj, :qux, :pri => 5000, :queue => "qux", :shard_key => "abc")
|
57
57
|
|
58
|
-
Backburner::Worker.expects(:enqueue).with(AutomagicTestObj, [56, :qux_without_async, true, false], has_entries(:pri => 5000, :queue => "qux"))
|
58
|
+
Backburner::Worker.expects(:enqueue).with(AutomagicTestObj, [56, :qux_without_async, true, false], has_entries(:pri => 5000, :queue => "qux", :shard_key => "abc"))
|
59
59
|
AutomagicTestObj.new.qux(true, false)
|
60
60
|
end
|
61
61
|
|
62
62
|
it "should work for class methods, too" do
|
63
|
-
Backburner::Performable.handle_static_asynchronously(AutomagicTestObj, :garply, :pri => 5000, :queue => "garply")
|
63
|
+
Backburner::Performable.handle_static_asynchronously(AutomagicTestObj, :garply, :pri => 5000, :queue => "garply", :shard_key => "abc")
|
64
64
|
|
65
|
-
Backburner::Worker.expects(:enqueue).with(AutomagicTestObj, [nil, :garply_without_async, true, false], has_entries(:pri => 5000, :queue => "garply"))
|
65
|
+
Backburner::Worker.expects(:enqueue).with(AutomagicTestObj, [nil, :garply_without_async, true, false], has_entries(:pri => 5000, :queue => "garply", :shard_key => "abc"))
|
66
66
|
AutomagicTestObj.garply(true, false)
|
67
67
|
end
|
68
68
|
|
@@ -74,14 +74,14 @@ describe "Backburner::Performable module" do
|
|
74
74
|
end
|
75
75
|
|
76
76
|
it "should be available for instance methods on any class that includes the Performable module" do
|
77
|
-
AsyncInstanceMethodsTestObj.handle_asynchronously :foo, pri: 5000, queue: 'qux'
|
78
|
-
Backburner::Worker.expects(:enqueue).with(AsyncInstanceMethodsTestObj, [56, :foo_without_async, true, false], has_entries(:pri => 5000, :queue => "qux"))
|
77
|
+
AsyncInstanceMethodsTestObj.handle_asynchronously :foo, pri: 5000, queue: 'qux', shard_key: "abc"
|
78
|
+
Backburner::Worker.expects(:enqueue).with(AsyncInstanceMethodsTestObj, [56, :foo_without_async, true, false], has_entries(:pri => 5000, :queue => "qux", :shard_key => "abc"))
|
79
79
|
AsyncInstanceMethodsTestObj.new.foo(true, false)
|
80
80
|
end
|
81
81
|
|
82
82
|
it "should be available for class methods on any class that includes the Performable module" do
|
83
|
-
AsyncStaticMethodsTestObj.handle_static_asynchronously :bar, pri: 5000, queue: 'garply'
|
84
|
-
Backburner::Worker.expects(:enqueue).with(AsyncStaticMethodsTestObj, [nil, :bar_without_async, true, false], has_entries(:pri => 5000, :queue => "garply"))
|
83
|
+
AsyncStaticMethodsTestObj.handle_static_asynchronously :bar, pri: 5000, queue: 'garply', shard_key: "abc"
|
84
|
+
Backburner::Worker.expects(:enqueue).with(AsyncStaticMethodsTestObj, [nil, :bar_without_async, true, false], has_entries(:pri => 5000, :queue => "garply",:shard_key => "abc"))
|
85
85
|
AsyncStaticMethodsTestObj.bar(true, false)
|
86
86
|
end
|
87
87
|
end
|
data/test/test_helper.rb
CHANGED
@@ -12,7 +12,7 @@ require File.expand_path('../helpers/templogger', __FILE__)
|
|
12
12
|
|
13
13
|
# Configure Backburner
|
14
14
|
Backburner.configure do |config|
|
15
|
-
config.
|
15
|
+
config.allq_url = "allq://127.0.0.1:8091"
|
16
16
|
config.tube_namespace = "demo.test"
|
17
17
|
end
|
18
18
|
|
@@ -88,7 +88,7 @@ class MiniTest::Spec
|
|
88
88
|
end
|
89
89
|
|
90
90
|
def beanstalk_connection
|
91
|
-
Backburner::Connection.new(Backburner.configuration.
|
91
|
+
Backburner::Connection.new(Backburner.configuration.allq_url)
|
92
92
|
end
|
93
93
|
|
94
94
|
# pop_one_job(tube_name)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: backburner-allq
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.38
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jason Malcolm
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-07-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: allq_rest
|