backburner-allq 1.0.38 → 1.0.40

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1d44569a854f2a26375e77a62b485851cc1970bd7bacce5948178c65e17a1f27
4
- data.tar.gz: 29d4a2408a0d7b77c6236a2fd716a07c9ddad32e1566d5d5575c99d557fcb7bf
3
+ metadata.gz: 682416738c55b9567c39530b31bfc92a8d9115b51c640494b067c9ff23cca65d
4
+ data.tar.gz: 9239e634bea3dc41131c9a4deb56d5998b6f4745e891c43a90fad4c569008c0c
5
5
  SHA512:
6
- metadata.gz: 9ea4a8b0da3978fe8567ecf7edbb4157246ad88da2acf9352038627e665f2240d877511e6f49f3775d42a54d61617c79dbbee2ccb71413a76797f1c77b01218d
7
- data.tar.gz: 9e2be902d44f1600e86941c714c8bb09e2e902c636cba0cc34fd26a2fb901e79006e48df357877a3c3cc248966090561b37d4b10d5c6d0f207d5b7ab3be4e0e5
6
+ metadata.gz: 127ae4b11fcc7651aeed81e9070a791460b2256fb2d308b559e70e9c4ba767d6c8cce5feed450e783c22415f84757e248d4b70de3fb27612317fb14283794b60
7
+ data.tar.gz: 06e8e765a1f8a6fd55ce3c0405bd319e797c59d87f5f54cebdee9bba2804d888cd8f4765bb8e02935d5b96dde7c38a756df073610106d8df8243f5dc16694f7f
data/.gitlab-ci.yml ADDED
@@ -0,0 +1,21 @@
1
+ default:
2
+ image: ruby:3.0
3
+
4
+ stages: # List of stages for jobs, and their order of execution
5
+ - test
6
+
7
+ unit-test:
8
+ tags:
9
+ - allq
10
+ stage: test
11
+ script:
12
+ - docker-compose down || true
13
+ - docker-compose up -d || true
14
+ - sleep 10
15
+ - ruby -v
16
+ - bundle install
17
+ - bundle exec rake test TEST=test/allq/back_burner_test.rb DEBUG=true
18
+ - bundle exec rake test TEST=test/allq/worker_test.rb DEBUG=true
19
+ after_script:
20
+ - docker-compose down || true
21
+
data/deploy.sh CHANGED
@@ -1,3 +1,3 @@
1
1
  echo "Did you update the version?"
2
2
  gem build backburner-allq.gemspec
3
- gem push backburner-allq-1.0.38.gem
3
+ gem push backburner-allq-1.0.40.gem
@@ -0,0 +1,26 @@
1
+ version: '3'
2
+ services:
3
+ allq-client:
4
+ networks:
5
+ - local-net
6
+ image: "blitline/allq_client"
7
+ environment:
8
+ - SERVER_STRING=allq-server:5555
9
+ depends_on:
10
+ - allq-server
11
+ ports:
12
+ - 8090:8090
13
+ restart: unless-stopped
14
+ healthcheck:
15
+ test: ["CMD-SHELL", "echo '{\"action\":\"peek\",\"params\":{\"tube\":\"default\", \"buried\":true}}' | socat - tcp4-connect:127.0.0.1:7768"]
16
+ interval: 1m
17
+ timeout: 10s
18
+ retries: 3
19
+ allq-server:
20
+ networks:
21
+ - local-net
22
+ image: "blitline/allq_server"
23
+ restart: unless-stopped
24
+ networks:
25
+ local-net:
26
+
@@ -82,6 +82,10 @@ module Backburner
82
82
  def stats
83
83
  { 'expireds' => expireds, 'releases' => releases }
84
84
  end
85
+
86
+ def clear(tube)
87
+ @client.clear(tube)
88
+ end
85
89
  end
86
90
 
87
91
  class AllQWrapper
@@ -97,6 +101,10 @@ module Backburner
97
101
  @recent_times = []
98
102
  end
99
103
 
104
+ def clear(tube)
105
+ @client.tube_delete(tube)
106
+ end
107
+
100
108
  def touch(job)
101
109
  @client.touch_put(job.id)
102
110
  end
@@ -21,7 +21,7 @@ module Backburner
21
21
  attr_accessor :job_parser_proc # proc to parse a job body from a string
22
22
 
23
23
  def initialize
24
- @allq_url = "allq://127.0.0.1:8091"
24
+ @allq_url = "allq://127.0.0.1:8090"
25
25
  @tube_namespace = "backburner"
26
26
  @namespace_separator = "."
27
27
  @default_priority = 5
@@ -23,6 +23,10 @@ module Backburner
23
23
  connect!
24
24
  end
25
25
 
26
+ def clear(tube)
27
+ @allq_wrapper.clear(tube)
28
+ end
29
+
26
30
  # Close the connection, if it exists
27
31
  def close
28
32
  @allq_wrapper.close if @allq_wrapper
@@ -110,6 +114,11 @@ module Backburner
110
114
  }
111
115
 
112
116
  options[:shard_key] = opt[:shard_key] if opt[:shard_key]
117
+ options[:parent_id] = opt[:parent_id] if opt[:parent_id]
118
+ options[:timeout] = opt[:timeout] if opt[:timeout]
119
+ options[:run_on_timeout] = opt[:run_on_timeout] if opt[:run_on_timeout]
120
+ options[:limit] = opt[:limit] if opt[:limit]
121
+ options[:is_parent] = opt[:is_parent] if opt[:is_parent]
113
122
 
114
123
  # Overwrite originals
115
124
  opt.merge!(options)
@@ -26,11 +26,6 @@ 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
-
34
29
  rescue => ex # Job was not valid format
35
30
  # self.bury
36
31
  # raise JobFormatInvalid, "Job body could not be parsed: #{ex.inspect}"
@@ -54,9 +49,28 @@ module Backburner
54
49
  return false unless res
55
50
  # Execute the job
56
51
  @hooks.around_hook_events(job_name, :around_perform, *args) do
57
- timeout_job_after(@ttr > 1 ? @ttr - 1 : @ttr) { job_class.perform(*args) }
52
+
53
+ timeout_job_after(@ttr > 1 ? @ttr - 1 : @ttr) do
54
+ # Decide if we want access to the root task
55
+ if job_class.methods.include?(:perform_with_task)
56
+ job_class.perform_with_task(@task, *args)
57
+ else
58
+ job_class.perform(*args)
59
+ end
60
+ end
61
+ end
62
+
63
+ retry_count = 0
64
+ begin
65
+ task.delete
66
+ rescue StandardError => allqex
67
+ retry_count += 1
68
+
69
+ puts "Failed to delete task, waiting #{retry_count * 10}secs"
70
+ sleep(retry_count * 10)
71
+ retry if retry_count < 3
58
72
  end
59
- task.delete
73
+
60
74
  # Invoke after perform hook
61
75
  @hooks.invoke_hook_events(job_name, :after_perform, *args)
62
76
  rescue => e
@@ -1,3 +1,3 @@
1
1
  module Backburner
2
- VERSION = "1.0.38"
2
+ VERSION = "1.0.40"
3
3
  end
@@ -168,25 +168,6 @@ module Backburner
168
168
  return
169
169
  end
170
170
 
171
- # NB: There's a slight chance here that the connection to allq has
172
- # gone down between the time we reserved / processed the job and here.
173
- num_retries = job.releases
174
- max_job_retries = resolve_max_job_retries(job.job_class)
175
- retry_status = "failed: attempt #{num_retries + 1} of #{max_job_retries + 1}"
176
- retry_delay = resolve_retry_delay(job.job_class)
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
-
183
- if num_retries + 1 > max_job_retries
184
- job.bury
185
- else
186
- job.release(delay)
187
- end
188
- log_job_end(job.name, "#{retry_status}, retrying in #{delay}s") if job_started_at
189
-
190
171
  handle_error(e, job.name, job.args, job)
191
172
  end
192
173
  else
@@ -0,0 +1,74 @@
1
+ require File.expand_path('test_helper', __dir__)
2
+
3
+ $backburner_sum = 0
4
+ $backburner_numbers = []
5
+
6
+ class TestBackburnerJob
7
+ include Backburner::Queue
8
+ queue 'test.jobber'
9
+
10
+ def self.perform(value, number)
11
+ $backburner_sum += value
12
+ $backburner_numbers << number
13
+ end
14
+ end
15
+
16
+ class TestWorker < Backburner::Worker; end
17
+
18
+ describe 'Backburner module' do
19
+ before do
20
+ Backburner.default_queues.clear
21
+ clear_jobs!(Backburner.configuration.primary_queue, 'test-plain', 'parent-plain', 'bar.baz.foo')
22
+ end
23
+
24
+ describe 'for work method' do
25
+ it 'invokes worker simple start' do
26
+ Backburner::Workers::Simple.expects(:start).with(%w[foo bar])
27
+ Backburner.work('foo', 'bar')
28
+ end
29
+
30
+ it 'invokes other worker if specified in configuration' do
31
+ Backburner.configure { |config| config.default_worker = TestWorker }
32
+ TestWorker.expects(:start).with(%w[foo bar])
33
+ Backburner.work('foo', 'bar')
34
+ end
35
+
36
+ it 'invokes other worker if specified in work method as options' do
37
+ TestWorker.expects(:start).with(%w[foo bar])
38
+ Backburner.work('foo', 'bar', worker: TestWorker)
39
+ end
40
+
41
+ it 'invokes worker start with no args' do
42
+ Backburner::Workers::Simple.expects(:start).with([])
43
+ Backburner.work
44
+ end
45
+ end # work!
46
+
47
+ describe 'for configuration' do
48
+ it 'remembers the tube_namespace' do
49
+ assert_equal 'demo.test', Backburner.configuration.tube_namespace
50
+ end
51
+
52
+ it 'remembers the namespace_separator' do
53
+ assert_equal '.', Backburner.configuration.namespace_separator
54
+ end
55
+
56
+ it 'disallows a reserved separator' do
57
+ assert_raises RuntimeError do
58
+ Backburner.configuration.namespace_separator = ':'
59
+ end
60
+ end
61
+ end # configuration
62
+
63
+ describe 'for default_queues' do
64
+ it 'supports assignment' do
65
+ Backburner.default_queues << 'foo'
66
+ Backburner.default_queues << 'bar'
67
+ assert_same_elements %w[foo bar], Backburner.default_queues
68
+ end
69
+ end
70
+
71
+ after do
72
+ Backburner.configure { |config| config.default_worker = Backburner::Workers::Simple }
73
+ end
74
+ end # Backburner
@@ -0,0 +1,108 @@
1
+ $LOAD_PATH.unshift File.expand_path("lib")
2
+ require 'backburner'
3
+ require 'tempfile'
4
+ require 'minitest/autorun'
5
+ require_relative '../fixtures/test_jobs'
6
+
7
+ begin
8
+ require 'mocha/setup'
9
+ rescue LoadError
10
+ require 'mocha'
11
+ end
12
+
13
+ # Configure Backburner
14
+ Backburner.configure do |config|
15
+ config.allq_url = "allq://127.0.0.1:8090"
16
+ config.tube_namespace = "demo.test"
17
+ config.on_error = lambda { |e| puts e }
18
+ end
19
+
20
+ def clear_jobs!(*tube_names)
21
+ connection = allq_connection
22
+ tube_names.each do |tube_name|
23
+ expanded_name = [Backburner.configuration.tube_namespace, tube_name].join(".")
24
+ connection.clear(expanded_name)
25
+ end
26
+ ensure
27
+ connection.close if connection
28
+ end
29
+
30
+ def allq_connection
31
+ Backburner::Connection.new(Backburner.configuration.allq_url)
32
+ end
33
+
34
+ module Kernel
35
+ # Redirect standard out, standard error and the buffered logger for sprinkle to StringIO
36
+ # capture_stdout { any_commands; you_want } => "all output from the commands"
37
+ def capture_stdout
38
+ if ENV['DEBUG'] # Skip if debug mode
39
+ yield
40
+ return ""
41
+ end
42
+
43
+ out = StringIO.new
44
+ $stdout = out
45
+ $stderr = out
46
+ yield
47
+ return out.string
48
+ ensure
49
+ $stdout = STDOUT
50
+ $stderr = STDERR
51
+ end
52
+ end
53
+
54
+ def sleeper(duration_in_seconds)
55
+ 1.upto(duration_in_seconds) do |i|
56
+ sleep(1)
57
+ print '.'
58
+ end
59
+ end
60
+
61
+ # pop_one_job(tube_name)
62
+ def pop_one_job(tube_name=Backburner.configuration.primary_queue)
63
+ tube_name = [Backburner.configuration.tube_namespace, tube_name].join(".")
64
+ connection = allq_connection
65
+ silenced(3) { @res = connection.get(tube_name)}
66
+ data = nil
67
+ data = Backburner.configuration.job_parser_proc.call(@res.body) if @res && @res.body
68
+ yield @res, data
69
+ ensure
70
+ connection.close if connection
71
+ end
72
+
73
+ # def work_one_job(tube_name=Backburner.configuration.primary_queue)
74
+ # tube_name = [Backburner.configuration.tube_namespace, tube_name].join(".")
75
+ # connection = allq_connection
76
+ # job = Backburner::Worker.work_one_job(connection, tube_name)
77
+ # job.delete
78
+ # end
79
+
80
+ def assert_same_elements(a1, a2, msg = nil)
81
+ [:select, :inject, :size].each do |m|
82
+ [a1, a2].each {|a| assert_respond_to(a, m, "Are you sure that #{a.inspect} is an array? It doesn't respond to #{m}.") }
83
+ end
84
+
85
+ assert a1h = a1.inject({}) { |h,e| h[e] ||= a1.select { |i| i == e }.size; h }
86
+ assert a2h = a2.inject({}) { |h,e| h[e] ||= a2.select { |i| i == e }.size; h }
87
+
88
+ assert_equal(a1h, a2h, msg)
89
+ end
90
+
91
+ # assert_contains(['a', '1'], /\d/) => passes
92
+ # assert_contains(['a', '1'], 'a') => passes
93
+ # assert_contains(['a', '1'], /not there/) => fails
94
+ def assert_contains(collection, x, extra_msg = "")
95
+ collection = [collection] unless collection.is_a?(Array)
96
+ msg = "#{x.inspect} not found in #{collection.to_a.inspect} #{extra_msg}"
97
+ case x
98
+ when Regexp
99
+ assert(collection.detect { |e| e =~ x }, msg)
100
+ else
101
+ assert(collection.include?(x), msg)
102
+ end
103
+ end
104
+
105
+ # silenced(5) { ... }
106
+ def silenced(time=3, &block)
107
+ Timeout::timeout(time) { capture_stdout(&block) }
108
+ end
@@ -0,0 +1,82 @@
1
+ require File.expand_path('test_helper', __dir__)
2
+
3
+ describe 'Backburner::Worker module' do
4
+ before do
5
+ Backburner.default_queues.clear
6
+ clear_jobs!(Backburner.configuration.primary_queue, 'test-plain', 'parent-plain', 'bar.baz.foo')
7
+ end
8
+
9
+ it 'should support enqueuing plain job' do
10
+ Backburner::Worker.enqueue TestPlainJob, [7, 9], { ttr: 144 }
11
+ pop_one_job('test-plain') do |_job, body|
12
+ assert_equal 'TestPlainJob', body['class']
13
+ assert_equal [7, 9], body['args']
14
+ assert_equal 144, body['ttr'].to_i
15
+ end
16
+ end # plain
17
+
18
+ it 'should support enqueuing parent job' do
19
+ options = {
20
+ is_parent: true,
21
+ limit: 1,
22
+ timeout: 3,
23
+ run_on_timeout: true
24
+ }
25
+ # Enqueue parent job
26
+ response = Backburner::Worker.enqueue TestParentJob, [17, 9], options
27
+
28
+ options = {
29
+ parent_id: response.job_id
30
+ }
31
+ # Enqueue child job
32
+ Backburner::Worker.enqueue TestPlainJob, [7, 9], options
33
+ pop_one_job('test-plain') do |job, body|
34
+ assert_equal 'TestPlainJob', body['class']
35
+ assert_equal [7, 9], body['args']
36
+ job.delete
37
+ end
38
+
39
+ pop_one_job('parent-plain') do |_job, body|
40
+ assert_equal [17, 9], body['args']
41
+ end
42
+ end
43
+
44
+ it 'should support enqueuing parent job with timeout' do
45
+ options = {
46
+ is_parent: true,
47
+ limit: 1,
48
+ timeout: 3,
49
+ run_on_timeout: true
50
+ }
51
+ # Enqueue parent job
52
+ response = Backburner::Worker.enqueue TestParentJob, [17, 9], options
53
+
54
+ options = {
55
+ parent_id: response.job_id
56
+ }
57
+ # Enqueue child job
58
+ Backburner::Worker.enqueue TestPlainJob, [7, 9], options
59
+
60
+ pop_one_job('parent-plain') do |_job, body|
61
+ assert_equal body, nil
62
+ sleeper(10)
63
+ end
64
+
65
+ worker = Backburner::Workers::Simple.new('demo.test.parent-plain')
66
+ worker.prepare
67
+
68
+ TestParentJob.expects(:perform_with_task)
69
+ job = worker.work_one_job(allq_connection, 'demo.test.parent-plain')
70
+ assert_equal job.special, "true"
71
+ end
72
+
73
+
74
+
75
+ end
76
+
77
+
78
+ # options[:parent_id] = opt[:parent_id] if opt[:parent_id]
79
+ # options[:timeout] = opt[:timeout] if opt[:timeout]
80
+ # options[:run_on_timeout] = opt[:run_on_timeout] if opt[:run_on_timeout]
81
+ # options[:limit] = opt[:limit] if opt[:limit]
82
+ # options[:is_parent] = opt[:is_parent] if opt[:is_parent]
@@ -6,6 +6,18 @@ class TestPlainJob
6
6
  def self.perform(x, y); $worker_test_count += x + y + 1; end
7
7
  end
8
8
 
9
+
10
+ class TestParentJob
11
+ def self.queue; "parent-plain"; end
12
+ def self.perform(args)
13
+ puts "plain perform #{args}"
14
+ end
15
+ def self.perform_with_task(task, *args)
16
+ puts "perform_with_task"
17
+ puts task.inspect
18
+ end
19
+ end
20
+
9
21
  class TestJob
10
22
  include Backburner::Queue
11
23
  queue_priority :medium
data/test/worker_test.rb CHANGED
@@ -1,6 +1,4 @@
1
1
  require File.expand_path('../test_helper', __FILE__)
2
- require File.expand_path('../fixtures/test_jobs', __FILE__)
3
- require File.expand_path('../fixtures/hooked', __FILE__)
4
2
 
5
3
  describe "Backburner::Worker module" do
6
4
  before do
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.38
4
+ version: 1.0.40
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jason Malcolm
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-07-27 00:00:00.000000000 Z
11
+ date: 2022-10-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: allq_rest
@@ -109,6 +109,7 @@ extensions: []
109
109
  extra_rdoc_files: []
110
110
  files:
111
111
  - ".gitignore"
112
+ - ".gitlab-ci.yml"
112
113
  - ".travis.yml"
113
114
  - CHANGELOG.md
114
115
  - CONTRIBUTING.md
@@ -122,6 +123,7 @@ files:
122
123
  - bin/backburner
123
124
  - circle.yml
124
125
  - deploy.sh
126
+ - docker-compose.yml
125
127
  - examples/custom.rb
126
128
  - examples/demo.rb
127
129
  - examples/god.rb
@@ -148,6 +150,9 @@ files:
148
150
  - lib/backburner/workers/simple.rb
149
151
  - lib/backburner/workers/threading.rb
150
152
  - lib/backburner/workers/threads_on_fork.rb
153
+ - test/allq/back_burner_test.rb
154
+ - test/allq/test_helper.rb
155
+ - test/allq/worker_test.rb
151
156
  - test/async_proxy_test.rb
152
157
  - test/back_burner_test.rb
153
158
  - test/connection_test.rb
@@ -193,6 +198,9 @@ signing_key:
193
198
  specification_version: 4
194
199
  summary: Reliable allq background job processing made easy for Ruby and Sinatra
195
200
  test_files:
201
+ - test/allq/back_burner_test.rb
202
+ - test/allq/test_helper.rb
203
+ - test/allq/worker_test.rb
196
204
  - test/async_proxy_test.rb
197
205
  - test/back_burner_test.rb
198
206
  - test/connection_test.rb