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.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +53 -4
  3. data/HOOKS.md +23 -14
  4. data/README.md +102 -23
  5. data/bin/backburner +1 -1
  6. data/lib/active_job/queue_adapters/backburner_adapter.rb +19 -5
  7. data/lib/backburner/cli.rb +1 -1
  8. data/lib/backburner/configuration.rb +7 -0
  9. data/lib/backburner/connection.rb +4 -2
  10. data/lib/backburner/enqueue_pool.rb +90 -0
  11. data/lib/backburner/helpers.rb +77 -22
  12. data/lib/backburner/job.rb +46 -7
  13. data/lib/backburner/logger.rb +9 -0
  14. data/lib/backburner/performable.rb +29 -4
  15. data/lib/backburner/queue.rb +37 -19
  16. data/lib/backburner/version.rb +1 -1
  17. data/lib/backburner/worker.rb +150 -25
  18. data/lib/backburner/workers/forking.rb +4 -2
  19. data/lib/backburner/workers/simple.rb +5 -0
  20. data/lib/backburner/workers/threading.rb +17 -7
  21. data/lib/backburner/workers/threads_on_fork.rb +59 -23
  22. data/lib/backburner.rb +7 -1
  23. metadata +40 -66
  24. data/.gitignore +0 -17
  25. data/.travis.yml +0 -29
  26. data/CONTRIBUTING.md +0 -37
  27. data/Gemfile +0 -4
  28. data/Rakefile +0 -17
  29. data/TODO +0 -4
  30. data/backburner.gemspec +0 -28
  31. data/circle.yml +0 -3
  32. data/examples/custom.rb +0 -25
  33. data/examples/demo.rb +0 -60
  34. data/examples/god.rb +0 -46
  35. data/examples/hooked.rb +0 -87
  36. data/examples/retried.rb +0 -31
  37. data/examples/simple.rb +0 -43
  38. data/examples/stress.rb +0 -31
  39. data/test/async_proxy_test.rb +0 -36
  40. data/test/back_burner_test.rb +0 -88
  41. data/test/connection_test.rb +0 -179
  42. data/test/fixtures/active_jobs.rb +0 -11
  43. data/test/fixtures/hooked.rb +0 -122
  44. data/test/fixtures/test_fork_jobs.rb +0 -72
  45. data/test/fixtures/test_forking_jobs.rb +0 -56
  46. data/test/fixtures/test_jobs.rb +0 -87
  47. data/test/fixtures/test_queue_settings.rb +0 -14
  48. data/test/helpers/templogger.rb +0 -22
  49. data/test/helpers_test.rb +0 -278
  50. data/test/hooks_test.rb +0 -112
  51. data/test/job_test.rb +0 -185
  52. data/test/logger_test.rb +0 -44
  53. data/test/performable_test.rb +0 -88
  54. data/test/queue_test.rb +0 -69
  55. data/test/test_helper.rb +0 -125
  56. data/test/worker_test.rb +0 -157
  57. data/test/workers/forking_worker_test.rb +0 -181
  58. data/test/workers/simple_worker_test.rb +0 -350
  59. data/test/workers/threading_worker_test.rb +0 -104
  60. data/test/workers/threads_on_fork_worker_test.rb +0 -484
@@ -1,179 +0,0 @@
1
- require File.expand_path('../test_helper', __FILE__)
2
-
3
- describe "Backburner::Connection class" do
4
- describe "for initialize with single url" do
5
- before do
6
- @connection = Backburner::Connection.new("beanstalk://127.0.0.1")
7
- end
8
-
9
- it "should store url in accessor" do
10
- assert_equal "beanstalk://127.0.0.1", @connection.url
11
- end
12
-
13
- it "should setup beanstalk connection" do
14
- assert_kind_of Beaneater, @connection.beanstalk
15
- end
16
- end # initialize single connection
17
-
18
- describe "for initialize with url" do
19
- it "should delegate the address url correctly" do
20
- @connection = Backburner::Connection.new("beanstalk://127.0.0.1")
21
- connection = @connection.beanstalk.connection
22
- assert_equal '127.0.0.1:11300', connection.address
23
- end
24
- end # initialize
25
-
26
- describe "for bad uri" do
27
- it "should raise a BadUrl" do
28
- assert_raises(Backburner::Connection::BadURL) {
29
- @connection = Backburner::Connection.new("fake://foo")
30
- }
31
- end
32
- end
33
-
34
- describe "for initialize with on_reconnect block" do
35
- it "should store the block for use upon reconnect" do
36
- callback = proc {}
37
- connection = Backburner::Connection.new('beanstalk://127.0.0.1', &callback)
38
- assert_equal callback, connection.on_reconnect
39
- end
40
- end
41
-
42
- describe "dealing with connecting and reconnecting" do
43
- before do
44
- @connection = Backburner::Connection.new('beanstalk://127.0.0.1')
45
- end
46
-
47
- it "should know if its connection is open" do
48
- assert_equal true, @connection.connected?
49
- @connection.close
50
- assert_equal false, @connection.connected?
51
- end
52
-
53
- it "should be able to attempt reconnecting to beanstalk" do
54
- @connection.close
55
- assert_equal false, @connection.connected?
56
- @connection.reconnect!
57
- assert_equal true, @connection.connected?
58
- end
59
-
60
- it "should allow for retryable commands" do
61
- @result = false
62
- @connection.close
63
- @connection.retryable { @result = true }
64
- assert_equal true, @result
65
- end
66
-
67
- it "should provide a hook when a retryable command successfully retries" do
68
- @result = false
69
- @retried = false
70
- @connection.close
71
- callback = proc { @result = true }
72
- @connection.retryable(:on_retry => callback) do
73
- unless @retried
74
- @retried = true
75
- raise Beaneater::NotConnected.new
76
- end
77
- end
78
- assert_equal true, @result
79
- end
80
-
81
- it "should provide a hook when the connection successfully reconnects" do
82
- reconnected = false
83
- retried = false
84
- @connection.close
85
- @connection.on_reconnect = proc { reconnected = true }
86
- @connection.retryable do
87
- unless retried
88
- retried = true
89
- raise Beaneater::NotConnected.new
90
- end
91
- end
92
- assert_equal true, reconnected
93
- end
94
-
95
- it "should call the on_reconnect hook before the on_retry hook" do
96
- @result = []
97
- @retried = false
98
- @connection.close
99
- @connection.on_reconnect = proc { @result << "reconnect" }
100
- on_retry = proc { @result << "retry" }
101
- @connection.retryable(:on_retry => on_retry) do
102
- unless @retried
103
- @retried = true
104
- raise Beaneater::NotConnected.new
105
- end
106
- end
107
- assert_equal %w(reconnect retry), @result
108
- end
109
-
110
- describe "ensuring the connection is open" do
111
- it "should reattempt the connection to beanstalk several times" do
112
- stats = @connection.stats
113
- simulate_disconnect(@connection)
114
- new_connection = Beaneater.new('127.0.0.1:11300')
115
- Beaneater.expects(:new).twice.raises(Beaneater::NotConnected).then.returns(new_connection)
116
- @connection.tubes
117
- assert_equal true, @connection.connected?
118
- end
119
-
120
- it "should not attempt reconnecting if the current connection is open" do
121
- assert_equal true, @connection.connected?
122
- Beaneater.expects(:new).never
123
- @connection.tubes
124
- end
125
-
126
- describe "when reconnecting is successful" do
127
- it "should allow for a callback" do
128
- @result = false
129
- simulate_disconnect(@connection)
130
- @connection.on_reconnect = proc { @result = true }
131
- @connection.tubes
132
- assert_equal true, @result
133
- end
134
-
135
- it "should pass self to the callback" do
136
- result = nil
137
- simulate_disconnect(@connection)
138
- @connection.on_reconnect = lambda { |conn| result = conn }
139
- @connection.tubes
140
- assert_equal result, @connection
141
- end
142
- end
143
- end
144
-
145
- describe "when unable to ensure its connected" do
146
- it "should raise Beaneater::NotConnected" do
147
- Beaneater.stubs(:new).raises(Beaneater::NotConnected)
148
- simulate_disconnect(@connection, 1) # since we're stubbing Beaneater.new above we only to simlulate the disconnect of our current connection
149
- assert_raises Beaneater::NotConnected do
150
- @connection.tubes
151
- end
152
- end
153
- end
154
-
155
- describe "when using the retryable method" do
156
- it "should yield to the block multiple times" do
157
- expected = 2
158
- retry_count = 0
159
- @connection.retryable(max_retries: expected) do
160
- if retry_count < 2
161
- retry_count += 1
162
- raise Beaneater::NotConnected
163
- end
164
- end
165
- assert_equal expected, retry_count
166
- end
167
- end
168
- end
169
-
170
- describe "for delegated methods" do
171
- before do
172
- @connection = Backburner::Connection.new("beanstalk://127.0.0.1")
173
- end
174
-
175
- it "delegate methods to beanstalk connection" do
176
- assert_equal "127.0.0.1", @connection.connection.host
177
- end
178
- end # delegator
179
- end # Connection
@@ -1,11 +0,0 @@
1
- require 'active_job'
2
- require 'active_job/queue_adapters/backburner_adapter'
3
-
4
- ActiveJob::Base.queue_adapter = :backburner
5
- ActiveJob::Base.logger = nil
6
-
7
- class TestJob < ActiveJob::Base
8
- def perform(arg)
9
- true
10
- end
11
- end
@@ -1,122 +0,0 @@
1
- $hooked_fail_count = 0
2
- class HookFailError < RuntimeError; end
3
-
4
- class HookedObjectBeforeEnqueueFail
5
- include Backburner::Performable
6
-
7
- def self.before_enqueue_abe(*args)
8
- puts "!!before_enqueue_foo!! #{args.inspect}"
9
- end
10
-
11
- def self.before_enqueue_bar(*args)
12
- return false
13
- end
14
- end
15
-
16
-
17
- class HookedObjectAfterEnqueueFail
18
- def self.after_enqueue_abe(*args)
19
- puts "!!after_enqueue_foo!! #{args.inspect}"
20
- end
21
-
22
- def self.after_enqueue_bar(*args)
23
- raise HookFailError, "Fail HookedObjectAfterEnqueueFail"
24
- end
25
- end
26
-
27
- class HookedObjectBeforePerformFail
28
- include Backburner::Performable
29
-
30
- def self.before_perform_abe(*args)
31
- puts "!!before_perform_foo!! #{args.inspect}"
32
- end
33
-
34
- def self.before_perform_foo(*args)
35
- return false
36
- end
37
-
38
- def self.foo(x)
39
- puts "Fail ran!!"
40
- raise HookFailError, "HookedObjectJobFailure on foo!"
41
- end
42
- end
43
-
44
- class HookedObjectAfterPerformFail
45
- def self.after_perform_abe(*args)
46
- puts "!!after_perform_foo!! #{args.inspect}"
47
- end
48
-
49
- def self.after_perform_bar(*args)
50
- raise HookFailError, "Fail HookedObjectAfterEnqueueFail"
51
- end
52
- end
53
-
54
- class HookedObjectJobFailure
55
- def self.foo(x)
56
- raise HookFailError, "HookedObjectJobFailure on foo!"
57
- end
58
- end
59
-
60
- class HookedObjectSuccess
61
- include Backburner::Performable
62
-
63
- def self.before_enqueue_foo(*args)
64
- puts "!!before_enqueue_foo!! #{args.inspect}"
65
- end
66
-
67
- def self.before_enqueue_bar(*args)
68
- puts "!!before_enqueue_bar!! #{args.inspect}"
69
- end
70
-
71
- def self.after_enqueue_foo(*args)
72
- puts "!!after_enqueue_foo!! #{args.inspect}"
73
- end
74
-
75
- def self.after_enqueue_bar(*args)
76
- puts "!!after_enqueue_bar!! #{args.inspect}"
77
- end
78
-
79
- def self.before_perform_foo(*args)
80
- puts "!!before_perform_foo!! #{args.inspect}"
81
- end
82
-
83
- def self.after_perform_foo(*args)
84
- puts "!!after_perform_foo!! #{args.inspect}"
85
- end
86
-
87
- def self.around_perform_bar(*args)
88
- puts "!!BEGIN around_perform_bar!! #{args.inspect}"
89
- yield
90
- puts "!!END around_perform_bar!! #{args.inspect}"
91
- end
92
-
93
- def self.around_perform_cat(*args)
94
- puts "!!BEGIN around_perform_cat!! #{args.inspect}"
95
- yield
96
- puts "!!END around_perform_cat!! #{args.inspect}"
97
- end
98
-
99
- def self.on_failure_foo(ex, *args)
100
- puts "!!on_failure_foo!! #{ex.inspect} #{args.inspect}"
101
- end
102
-
103
- def self.on_bury_foo(*args)
104
- puts "!!on_bury_foo!! #{args.inspect}"
105
- end
106
-
107
- def self.on_retry_foo(retry_count, delay, *args)
108
- puts "!!on_retry_foo!! #{retry_count} #{delay} #{args.inspect}"
109
- end
110
-
111
- def self.foo(x)
112
- $hooked_fail_count += 1
113
- raise HookFailError, "Fail!" if $hooked_fail_count == 1
114
- puts "This is the job running successfully!! #{x.inspect}"
115
- end
116
- end # HookedObjectSuccess
117
-
118
- class HookedWorker < Backburner::Worker
119
- def on_reconnect
120
- puts "!!on_reconnect!!"
121
- end
122
- end
@@ -1,72 +0,0 @@
1
- class ResponseJob
2
- include Backburner::Queue
3
- queue_priority 1000
4
- def self.perform(data)
5
- $worker_test_count += data['worker_test_count'].to_i if data['worker_test_count']
6
- $worker_success = data['worker_success'] if data['worker_success']
7
- $worker_test_count = data['worker_test_count_set'].to_i if data['worker_test_count_set']
8
- $worker_raise = data['worker_raise'] if data['worker_raise']
9
- end
10
- end
11
-
12
- class TestJobFork
13
- include Backburner::Queue
14
- queue "test-job-fork"
15
- queue_priority 1000
16
- def self.perform(x, y)
17
- Backburner::Workers::ThreadsOnFork.enqueue ResponseJob, [{
18
- :worker_test_count_set => x + y
19
- }], :queue => 'response'
20
- end
21
- end
22
-
23
- class TestFailJobFork
24
- include Backburner::Queue
25
- queue "test-fail-job-fork"
26
- def self.perform(x, y)
27
- Backburner::Workers::ThreadsOnFork.enqueue ResponseJob, [{
28
- :worker_raise => true
29
- }], :queue => 'response'
30
- end
31
- end
32
-
33
- class TestRetryJobFork
34
- include Backburner::Queue
35
- def self.perform(x, y)
36
- $worker_test_count += 1
37
-
38
- if $worker_test_count <= 2
39
- Backburner::Workers::ThreadsOnFork.enqueue ResponseJob, [{
40
- :worker_test_count => 1
41
- }], :queue => 'response'
42
-
43
- raise RuntimeError
44
- else # succeeds
45
- Backburner::Workers::ThreadsOnFork.enqueue ResponseJob, [{
46
- :worker_test_count => 1,
47
- :worker_success => true
48
- }], :queue => 'response'
49
- end
50
- end
51
- end
52
-
53
- class TestAsyncJobFork
54
- include Backburner::Performable
55
- def self.foo(x, y)
56
- Backburner::Workers::ThreadsOnFork.enqueue ResponseJob, [{
57
- :worker_test_count_set => x * y
58
- }], :queue => 'response'
59
- end
60
- end
61
-
62
- class TestJobMultithreadFork
63
- include Backburner::Queue
64
- queue "test-job-multithread-fork"
65
- queue_priority 1000
66
- def self.perform(x, y)
67
- sleep 1 # simluate work
68
- Backburner::Workers::ThreadsOnFork.enqueue ResponseJob, [{
69
- :worker_test_count_set => x + y
70
- }], :queue => 'response'
71
- end
72
- end
@@ -1,56 +0,0 @@
1
- class ResponseForkingJob
2
- include Backburner::Queue
3
- queue_priority 1000
4
- def self.perform(data)
5
- $worker_test_count += data['worker_test_count'].to_i if data['worker_test_count']
6
- $worker_success = data['worker_success'] if data['worker_success']
7
- $worker_test_count = data['worker_test_count_set'].to_i if data['worker_test_count_set']
8
- $worker_raise = data['worker_raise'] if data['worker_raise']
9
- end
10
- end
11
-
12
- class TestJobForking
13
- include Backburner::Queue
14
- queue_priority 1000
15
- def self.perform(x, y)
16
- Backburner::Workers::Forking.enqueue ResponseForkingJob, [{
17
- :worker_test_count_set => x + y
18
- }], :queue => 'response'
19
- end
20
- end
21
-
22
- class TestFailJobForking
23
- include Backburner::Queue
24
- def self.perform(x, y)
25
- Backburner::Workers::Forking.enqueue ResponseForkingJob, [{
26
- :worker_raise => true
27
- }], :queue => 'response'
28
- end
29
- end
30
-
31
- class TestRetryJobForking
32
- include Backburner::Queue
33
- def self.perform(x, y)
34
- if $worker_test_count <= 2
35
- Backburner::Workers::Forking.enqueue ResponseForkingJob, [{
36
- :worker_test_count => 1
37
- }], :queue => 'response'
38
-
39
- raise RuntimeError
40
- else # succeeds
41
- Backburner::Workers::Forking.enqueue ResponseForkingJob, [{
42
- :worker_test_count => 1,
43
- :worker_success => true
44
- }], :queue => 'response'
45
- end
46
- end
47
- end
48
-
49
- class TestAsyncJobForking
50
- include Backburner::Performable
51
- def self.foo(x, y)
52
- Backburner::Workers::Forking.enqueue ResponseForkingJob, [{
53
- :worker_test_count_set => x * y
54
- }], :queue => 'response'
55
- end
56
- end
@@ -1,87 +0,0 @@
1
- $worker_test_count = 0
2
- $worker_success = false
3
-
4
- class TestPlainJob
5
- def self.queue; "test-plain"; end
6
- def self.perform(x, y); $worker_test_count += x + y + 1; end
7
- end
8
-
9
- class TestJob
10
- include Backburner::Queue
11
- queue_priority :medium
12
- queue_respond_timeout 300
13
- def self.perform(x, y); $worker_test_count += x + y; end
14
- end
15
-
16
- class TestSlowJob
17
- include Backburner::Queue
18
- queue_priority :medium
19
- queue_respond_timeout 300
20
- def self.perform(x, y); sleep 1; $worker_test_count += x + y; end
21
- end
22
-
23
- class TestStuckJob
24
- include Backburner::Queue
25
- queue_priority :medium
26
- queue_respond_timeout 300
27
- def self.perform(_x, _y)
28
- loop do
29
- sleep 0.5
30
- end
31
- end
32
- end
33
-
34
- class TestFailJob
35
- include Backburner::Queue
36
- def self.perform(x, y); raise RuntimeError; end
37
- end
38
-
39
- class TestRetryJob
40
- include Backburner::Queue
41
- def self.perform(x, y)
42
- $worker_test_count += 1
43
- raise RuntimeError unless $worker_test_count > 2
44
- $worker_success = true
45
- end
46
- end
47
-
48
- class TestConfigurableRetryJob
49
- include Backburner::Queue
50
- def self.perform(retry_count)
51
- $worker_test_count += 1
52
- raise RuntimeError unless $worker_test_count > retry_count
53
- $worker_success = true
54
- end
55
- end
56
-
57
- class TestRetryWithQueueOverridesJob
58
- include Backburner::Queue
59
- def self.perform(retry_count)
60
- $worker_test_count += 1
61
- raise RuntimeError unless $worker_test_count > retry_count
62
- $worker_success = true
63
- end
64
-
65
- def self.queue_max_job_retries
66
- 3
67
- end
68
-
69
- def self.queue_retry_delay
70
- 0
71
- end
72
-
73
- def self.queue_retry_delay_proc
74
- lambda { |min_retry_delay, num_retries| min_retry_delay + (num_retries ** 2) }
75
- end
76
- end
77
-
78
- class TestAsyncJob
79
- include Backburner::Performable
80
- def self.foo(x, y); $worker_test_count = x * y; end
81
- end
82
-
83
- class TestLambdaQueueJob
84
- include Backburner::Queue
85
- queue lambda { |klass| klass.calculated_queue_name }
86
- def self.calculated_queue_name; 'lambda-queue' end
87
- end
@@ -1,14 +0,0 @@
1
- class TestJobSettings
2
- include Backburner::Queue
3
- queue "job-settings:5:10:6"
4
- def self.perform; end
5
- end
6
-
7
- class TestJobSettingsOverride
8
- include Backburner::Queue
9
- queue "job-settings-override:5:10:12"
10
- queue_jobs_limit 10
11
- queue_garbage_limit 1000
12
- queue_retry_limit 2
13
- def self.perform; end
14
- end
@@ -1,22 +0,0 @@
1
- class Templogger
2
- attr_reader :logger, :log_path
3
-
4
- def initialize(root_path)
5
- @file = Tempfile.new('foo', root_path)
6
- @log_path = @file.path
7
- @logger = Logger.new(@log_path)
8
- end
9
-
10
- # wait_for_match /Completed TestJobFork/m
11
- def wait_for_match(match_pattern)
12
- sleep 0.1 until self.body =~ match_pattern
13
- end
14
-
15
- def body
16
- File.read(@log_path)
17
- end
18
-
19
- def close
20
- @file.close
21
- end
22
- end