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,88 +0,0 @@
1
- require File.expand_path('../test_helper', __FILE__)
2
-
3
- class TestObj
4
- ID = 56
5
- def id; ID; end
6
- def self.find(id); TestObj.new if id == ID; end
7
- def foo(state, state2); "bar #{state} #{state2}"; end
8
- def self.bar(state, state2); "baz #{state} #{state2}"; end
9
- end
10
-
11
- class PerformableTestObj < TestObj
12
- include Backburner::Performable
13
- end
14
-
15
- class AutomagicTestObj < TestObj
16
- # Don't include Backburner::Performable because it should be automagically included
17
- def qux(state, state2); "garply #{state} #{state2}" end
18
- def self.garply(state, state2); "thud #{state} #{state2}" end
19
- def qux?; "garply!" end
20
- end
21
-
22
- class AsyncInstanceMethodsTestObj < PerformableTestObj; end
23
- class AsyncStaticMethodsTestObj < PerformableTestObj; end
24
-
25
-
26
-
27
- describe "Backburner::Performable module" do
28
- after { ENV["TEST"] = nil }
29
-
30
- describe "for async instance method" do
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)
34
- end
35
- end # async instance
36
-
37
- describe "for async class method" do
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)
41
- end
42
- end # async class
43
-
44
- describe "for perform class method" do
45
- it "should work for instance" do
46
- assert_equal "bar true false", PerformableTestObj.perform(PerformableTestObj::ID, :foo, true, false)
47
- end # instance
48
-
49
- it "should work for class level" do
50
- assert_equal "baz false true", PerformableTestObj.perform(nil, :bar, false, true)
51
- end # class
52
- end # perform
53
-
54
- describe "for handle_asynchronously class method" do
55
- it "should automagically asynchronously proxy calls to the method" do
56
- Backburner::Performable.handle_asynchronously(AutomagicTestObj, :qux, :pri => 5000, :queue => "qux")
57
-
58
- Backburner::Worker.expects(:enqueue).with(AutomagicTestObj, [56, :qux_without_async, true, false], has_entries(:pri => 5000, :queue => "qux"))
59
- AutomagicTestObj.new.qux(true, false)
60
- end
61
-
62
- it "should work for class methods, too" do
63
- Backburner::Performable.handle_static_asynchronously(AutomagicTestObj, :garply, :pri => 5000, :queue => "garply")
64
-
65
- Backburner::Worker.expects(:enqueue).with(AutomagicTestObj, [nil, :garply_without_async, true, false], has_entries(:pri => 5000, :queue => "garply"))
66
- AutomagicTestObj.garply(true, false)
67
- end
68
-
69
- it "should correctly handle punctuation" do
70
- Backburner::Performable.handle_asynchronously(AutomagicTestObj, :qux?)
71
-
72
- Backburner::Worker.expects(:enqueue).with(AutomagicTestObj, [56, :qux_without_async?], {})
73
- AutomagicTestObj.new.qux?
74
- end
75
-
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"))
79
- AsyncInstanceMethodsTestObj.new.foo(true, false)
80
- end
81
-
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"))
85
- AsyncStaticMethodsTestObj.bar(true, false)
86
- end
87
- end
88
- end
data/test/queue_test.rb DELETED
@@ -1,69 +0,0 @@
1
- require File.expand_path('../test_helper', __FILE__)
2
-
3
- module NestedDemo
4
- class TestJobA; include Backburner::Queue; end
5
- class TestJobB; include Backburner::Queue; end
6
- end
7
-
8
- describe "Backburner::Queue module" do
9
- describe "contains known_queue_classes" do
10
- it "has all defined known queues" do
11
- assert_contains Backburner::Worker.known_queue_classes, NestedDemo::TestJobA
12
- assert_contains Backburner::Worker.known_queue_classes, NestedDemo::TestJobB
13
- end
14
- end
15
-
16
- describe "for queue method accessor" do
17
- it "should return the queue name" do
18
- assert_equal Backburner.configuration.primary_queue, NestedDemo::TestJobA.queue
19
- end
20
- end # queue_name
21
-
22
- describe "for queue assignment method" do
23
- it "should allow queue name to be assigned" do
24
- NestedDemo::TestJobB.queue("nested/job")
25
- assert_equal "nested/job", NestedDemo::TestJobB.queue
26
- end
27
-
28
- it "should allow lambdas" do
29
- NestedDemo::TestJobB.queue(lambda { |klass| klass.name })
30
- assert_equal "NestedDemo::TestJobB", NestedDemo::TestJobB.queue
31
- end
32
- end # queue
33
-
34
- describe "for queue_priority assignment method" do
35
- it "should allow queue priority to be assigned" do
36
- NestedDemo::TestJobB.queue_priority(1000)
37
- assert_equal 1000, NestedDemo::TestJobB.queue_priority
38
- end
39
- end # queue_priority
40
-
41
- describe "for queue_respond_timeout assignment method" do
42
- it "should allow queue respond_timeout to be assigned" do
43
- NestedDemo::TestJobB.queue_respond_timeout(300)
44
- assert_equal 300, NestedDemo::TestJobB.queue_respond_timeout
45
- end
46
- end # queue_respond_timeout
47
-
48
- describe "for queue_max_job_retries assignment method" do
49
- it "should allow queue max_job_retries to be assigned" do
50
- NestedDemo::TestJobB.queue_max_job_retries(5)
51
- assert_equal 5, NestedDemo::TestJobB.queue_max_job_retries
52
- end
53
- end # queue_max_job_retries
54
-
55
- describe "for queue_retry_delay assignment method" do
56
- it "should allow queue retry_delay to be assigned" do
57
- NestedDemo::TestJobB.queue_retry_delay(300)
58
- assert_equal 300, NestedDemo::TestJobB.queue_retry_delay
59
- end
60
- end # queue_retry_delay
61
-
62
- describe "for queue_retry_delay_proc assignment method" do
63
- it "should allow queue retry_delay_proc to be assigned" do
64
- retry_delay_proc = lambda { |x, y| x - y }
65
- NestedDemo::TestJobB.queue_retry_delay_proc(retry_delay_proc)
66
- assert_equal retry_delay_proc.call(2, 1), NestedDemo::TestJobB.queue_retry_delay_proc.call(2, 1)
67
- end
68
- end # queue_retry_delay_proc
69
- end # Backburner::Queue
data/test/test_helper.rb DELETED
@@ -1,125 +0,0 @@
1
- require 'rubygems'
2
- require 'tempfile'
3
- require 'minitest/autorun'
4
- require 'mocha/minitest'
5
-
6
- $LOAD_PATH.unshift File.expand_path("lib")
7
- require 'backburner'
8
- require File.expand_path('../helpers/templogger', __FILE__)
9
-
10
- # Configure Backburner
11
- Backburner.configure do |config|
12
- config.beanstalk_url = "beanstalk://127.0.0.1"
13
- config.tube_namespace = "demo.test"
14
- end
15
-
16
- ## Kernel Extensions
17
- require 'stringio'
18
-
19
- module Kernel
20
- # Redirect standard out, standard error and the buffered logger for sprinkle to StringIO
21
- # capture_stdout { any_commands; you_want } => "all output from the commands"
22
- def capture_stdout
23
- if ENV['DEBUG'] # Skip if debug mode
24
- yield
25
- return ""
26
- end
27
-
28
- out = StringIO.new
29
- $stdout = out
30
- $stderr = out
31
- yield
32
- return out.string
33
- ensure
34
- $stdout = STDOUT
35
- $stderr = STDERR
36
- end
37
- end
38
-
39
- class User
40
- attr_accessor :id, :name
41
-
42
- def initialize(id, name)
43
- @id, @name = id, name
44
- end
45
- end
46
-
47
- class MiniTest::Spec
48
- class << self
49
- alias :should :it
50
- alias :context :describe
51
- end
52
- alias :assert_no_match :refute_match
53
- alias :assert_not_nil :refute_nil
54
- alias :assert_not_equal :refute_equal
55
-
56
- # assert_same_elements([:a, :b, :c], [:c, :a, :b]) => passes
57
- def assert_same_elements(a1, a2, msg = nil)
58
- [:select, :inject, :size].each do |m|
59
- [a1, a2].each {|a| assert_respond_to(a, m, "Are you sure that #{a.inspect} is an array? It doesn't respond to #{m}.") }
60
- end
61
-
62
- assert a1h = a1.inject({}) { |h,e| h[e] ||= a1.select { |i| i == e }.size; h }
63
- assert a2h = a2.inject({}) { |h,e| h[e] ||= a2.select { |i| i == e }.size; h }
64
-
65
- assert_equal(a1h, a2h, msg)
66
- end
67
-
68
- # assert_contains(['a', '1'], /\d/) => passes
69
- # assert_contains(['a', '1'], 'a') => passes
70
- # assert_contains(['a', '1'], /not there/) => fails
71
- def assert_contains(collection, x, extra_msg = "")
72
- collection = [collection] unless collection.is_a?(Array)
73
- msg = "#{x.inspect} not found in #{collection.to_a.inspect} #{extra_msg}"
74
- case x
75
- when Regexp
76
- assert(collection.detect { |e| e =~ x }, msg)
77
- else
78
- assert(collection.include?(x), msg)
79
- end
80
- end
81
-
82
- # silenced(5) { ... }
83
- def silenced(time=3, &block)
84
- Timeout::timeout(time) { capture_stdout(&block) }
85
- end
86
-
87
- def beanstalk_connection
88
- Backburner::Connection.new(Backburner.configuration.beanstalk_url)
89
- end
90
-
91
- # pop_one_job(tube_name)
92
- def pop_one_job(tube_name=Backburner.configuration.primary_queue)
93
- tube_name = [Backburner.configuration.tube_namespace, tube_name].join(".")
94
- connection = beanstalk_connection
95
- connection.tubes.watch!(tube_name)
96
- silenced(3) { @res = connection.tubes.reserve }
97
- yield @res, Backburner.configuration.job_parser_proc.call(@res.body)
98
- ensure
99
- connection.close if connection
100
- end
101
-
102
- # clear_jobs!('foo')
103
- def clear_jobs!(*tube_names)
104
- connection = beanstalk_connection
105
- tube_names.each do |tube_name|
106
- expanded_name = [Backburner.configuration.tube_namespace, tube_name].join(".")
107
- connection.tubes.find(expanded_name).clear
108
- end
109
- ensure
110
- connection.close if connection
111
- end
112
-
113
- # Simulates a broken connection for any Beaneater::Connection. Will
114
- # simulate a restored connection after `reconnects_after`. This is expected
115
- # to be used when ensuring a Beaneater connection is open, therefore
116
- def simulate_disconnect(connection, reconnects_after = 2)
117
- connection.beanstalk.connection.connection.expects(:closed? => true)
118
- returns = Array.new(reconnects_after - 1, stub('TCPSocket'))
119
- returns.each do |socket|
120
- result = (socket != returns.last)
121
- socket.stubs(:closed? => result)
122
- end
123
- TCPSocket.expects(:new).times(returns.size).returns(*returns)
124
- end
125
- end # MiniTest::Spec
data/test/worker_test.rb DELETED
@@ -1,157 +0,0 @@
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
-
5
- describe "Backburner::Worker module" do
6
- before do
7
- Backburner.default_queues.clear
8
- clear_jobs!(Backburner.configuration.primary_queue, "test-plain", "test.bar", "bar.baz.foo")
9
- end
10
-
11
- describe "for enqueue class method" do
12
- it "should support enqueuing plain job" do
13
- Backburner::Worker.enqueue TestPlainJob, [7, 9], :ttr => 100, :pri => 2000
14
- pop_one_job("test-plain") do |job, body|
15
- assert_equal "TestPlainJob", body["class"]
16
- assert_equal [7, 9], body["args"]
17
- assert_equal 100, job.ttr
18
- assert_equal 2000, job.pri
19
- end
20
- end # plain
21
-
22
- it "should support enqueuing job with class queue priority" do
23
- Backburner::Worker.enqueue TestJob, [3, 4], :ttr => 100
24
- pop_one_job do |job, body|
25
- assert_equal "TestJob", body["class"]
26
- assert_equal [3, 4], body["args"]
27
- assert_equal 100, job.ttr
28
- assert_equal 100, job.pri
29
- end
30
- end # queue priority
31
-
32
- it "should support enqueuing job with specified named priority" do
33
- Backburner::Worker.enqueue TestJob, [3, 4], :ttr => 100, :pri => 'high'
34
- pop_one_job do |job, body|
35
- assert_equal "TestJob", body["class"]
36
- assert_equal [3, 4], body["args"]
37
- assert_equal 100, job.ttr
38
- assert_equal 0, job.pri
39
- end
40
- end # queue named priority
41
-
42
- it "should support enqueuing job with class queue respond_timeout" do
43
- Backburner::Worker.enqueue TestJob, [3, 4]
44
- pop_one_job do |job, body|
45
- assert_equal "TestJob", body["class"]
46
- assert_equal [3, 4], body["args"]
47
- assert_equal 300, job.ttr
48
- assert_equal 100, job.pri
49
- end
50
- end # queue respond_timeout
51
-
52
- it "should support enqueuing job with custom queue" do
53
- Backburner::Worker.enqueue TestJob, [6, 7], :queue => "test.bar", :pri => 5000
54
- pop_one_job("test.bar") do |job, body|
55
- assert_equal "TestJob", body["class"]
56
- assert_equal [6, 7], body["args"]
57
- assert_equal 0, job.delay
58
- assert_equal 5000, job.pri
59
- assert_equal 300, job.ttr
60
- end
61
- end # custom
62
-
63
- it "should support async job" do
64
- TestAsyncJob.async(:ttr => 100, :queue => "bar.baz.foo").foo(10, 5)
65
- pop_one_job("bar.baz.foo") do |job, body|
66
- assert_equal "TestAsyncJob", body["class"]
67
- assert_equal [nil, "foo", 10, 5], body["args"]
68
- assert_equal 100, job.ttr
69
- assert_equal Backburner.configuration.default_priority, job.pri
70
- end
71
- end # async
72
-
73
- it "should support enqueueing job with lambda queue" do
74
- expected_queue_name = TestLambdaQueueJob.calculated_queue_name
75
- Backburner::Worker.enqueue TestLambdaQueueJob, [6, 7], :queue => lambda { |klass| klass.calculated_queue_name }
76
- pop_one_job(expected_queue_name) do |job, body|
77
- assert_equal "TestLambdaQueueJob", body["class"]
78
- assert_equal [6, 7], body["args"]
79
- end
80
- end
81
- end # enqueue
82
-
83
- describe "for start class method" do
84
- it "should initialize and start the worker instance" do
85
- ech = stub
86
- Backburner::Worker.expects(:new).with("foo").returns(ech)
87
- ech.expects(:start)
88
- Backburner::Worker.start("foo")
89
- end
90
- end # start
91
-
92
- describe "for tube_names accessor" do
93
- before do
94
- Backburner.default_queues << "baz"
95
- Backburner.default_queues << "bam"
96
- end
97
-
98
- it "supports retrieving tubes" do
99
- worker = Backburner::Worker.new(["foo", "bar"])
100
- assert_equal ["foo", "bar"], worker.tube_names
101
- end
102
-
103
- it "supports single tube array arg" do
104
- worker = Backburner::Worker.new([["foo", "bar"]])
105
- assert_equal ["foo", "bar"], worker.tube_names
106
- end
107
-
108
- it "supports empty nil array arg with default values" do
109
- worker = Backburner::Worker.new([nil])
110
- assert_equal ['baz', 'bam'], worker.tube_names
111
- end
112
-
113
- it "supports single tube arg" do
114
- worker = Backburner::Worker.new("foo")
115
- assert_equal ["foo"], worker.tube_names
116
- end
117
-
118
- it "supports empty array arg with default values" do
119
- worker = Backburner::Worker.new([])
120
- assert_equal ['baz', 'bam'], worker.tube_names
121
- end
122
-
123
- it "supports nil arg with default values" do
124
- worker = Backburner::Worker.new(nil)
125
- assert_equal ['baz', 'bam'], worker.tube_names
126
- end
127
- end # tube_names
128
-
129
- describe "for custom serialization" do
130
- before do
131
- Backburner.configure do |config|
132
- @old_parser = config.job_parser_proc
133
- @old_serializer = config.job_serializer_proc
134
- config.job_parser_proc = lambda { |body| Marshal.load(body) }
135
- config.job_serializer_proc = lambda { |body| Marshal.dump(body) }
136
- end
137
- end
138
-
139
- after do
140
- clear_jobs!('test-plain')
141
- Backburner.configure do |config|
142
- config.job_parser_proc = @old_parser
143
- config.job_serializer_proc = @old_serializer
144
- end
145
- end
146
-
147
- it "should support enqueuing a job" do
148
- Backburner::Worker.enqueue TestPlainJob, [7, 9], :ttr => 100, :pri => 2000
149
- pop_one_job("test-plain") do |job, body|
150
- assert_equal "TestPlainJob", body[:class]
151
- assert_equal [7, 9], body[:args]
152
- assert_equal 100, job.ttr
153
- assert_equal 2000, job.pri
154
- end
155
- end
156
- end # custom serialization
157
- end # Backburner::Worker
@@ -1,181 +0,0 @@
1
- require File.expand_path('../../test_helper', __FILE__)
2
- require File.expand_path('../../fixtures/test_forking_jobs', __FILE__)
3
-
4
- describe "Backburner::Workers::Forking module" do
5
-
6
- before do
7
- Backburner.default_queues.clear
8
- @worker_class = Backburner::Workers::Forking
9
- end
10
-
11
- describe "for prepare method" do
12
- it "should make tube names array always unique to avoid duplication" do
13
- worker = @worker_class.new(["foo", "demo.test.foo"])
14
- capture_stdout { worker.prepare }
15
- assert_equal ["demo.test.foo"], worker.tube_names
16
- end
17
-
18
- it "should watch specified tubes" do
19
- worker = @worker_class.new(["foo", "bar"])
20
- out = capture_stdout { worker.prepare }
21
- assert_equal ["demo.test.foo", "demo.test.bar"], worker.tube_names
22
- assert_same_elements ["demo.test.foo", "demo.test.bar"], worker.connection.tubes.watched.map(&:name)
23
- assert_match(/demo\.test\.foo/, out)
24
- end # multiple
25
-
26
- it "should watch single tube" do
27
- worker = @worker_class.new("foo")
28
- out = capture_stdout { worker.prepare }
29
- assert_equal ["demo.test.foo"], worker.tube_names
30
- assert_same_elements ["demo.test.foo"], worker.connection.tubes.watched.map(&:name)
31
- assert_match(/demo\.test\.foo/, out)
32
- end # single
33
-
34
- it "should respect default_queues settings" do
35
- Backburner.default_queues.concat(["foo", "bar"])
36
- worker = @worker_class.new
37
- out = capture_stdout { worker.prepare }
38
- assert_equal ["demo.test.foo", "demo.test.bar"], worker.tube_names
39
- assert_same_elements ["demo.test.foo", "demo.test.bar"], worker.connection.tubes.watched.map(&:name)
40
- assert_match(/demo\.test\.foo/, out)
41
- end
42
-
43
- it "should assign based on all tubes" do
44
- @worker_class.any_instance.expects(:all_existing_queues).once.returns("bar")
45
- worker = @worker_class.new
46
- out = capture_stdout { worker.prepare }
47
- assert_equal ["demo.test.bar"], worker.tube_names
48
- assert_same_elements ["demo.test.bar"], worker.connection.tubes.watched.map(&:name)
49
- assert_match(/demo\.test\.bar/, out)
50
- end # all assign
51
-
52
- it "should properly retrieve all tubes" do
53
- worker = @worker_class.new
54
- out = capture_stdout { worker.prepare }
55
- assert_contains worker.tube_names, "demo.test.backburner-jobs"
56
- assert_contains worker.connection.tubes.watched.map(&:name), "demo.test.backburner-jobs"
57
- assert_match(/demo\.test\.backburner-jobs/, out)
58
- end # all read
59
- end # prepare
60
-
61
- describe "for fork_one_job method" do
62
-
63
- it "should fork, work job, and exit" do
64
- clear_jobs!("bar.foo")
65
- @worker_class.enqueue TestJobForking, [1, 2], :queue => "bar.foo"
66
-
67
- fake_pid = 45
68
- Process.expects(:fork).returns(fake_pid).yields
69
- @worker_class.any_instance.expects(:work_one_job)
70
- @worker_class.any_instance.expects(:coolest_exit)
71
- Process.expects(:wait).with(fake_pid)
72
-
73
- silenced(2) do
74
- worker = @worker_class.new('bar.foo')
75
- worker.prepare
76
- worker.fork_one_job
77
- end
78
- end
79
-
80
- end # fork_one_job
81
-
82
- describe "practical tests" do
83
-
84
- before do
85
- @templogger = Templogger.new('/tmp')
86
- Backburner.configure { |config| config.logger = @templogger.logger }
87
- $worker_test_count = 0
88
- $worker_success = false
89
- $worker_raise = false
90
- clear_jobs!('response')
91
- clear_jobs!('bar.foo.1', 'bar.foo.2', 'bar.foo.3', 'bar.foo.4', 'bar.foo.5')
92
- silenced do
93
- @response_worker = @worker_class.new('response')
94
- end
95
- end
96
-
97
- after do
98
- @templogger.close
99
- Backburner.configuration.logger = nil
100
- clear_jobs!('response')
101
- clear_jobs!('bar.foo.1', 'bar.foo.2', 'bar.foo.3', 'bar.foo.4', 'bar.foo.5')
102
- end
103
-
104
-
105
- it "should work an enqueued job" do
106
- @worker = @worker_class.new('bar.foo.1')
107
- @worker_class.enqueue TestJobForking, [1, 2], :queue => "bar.foo.1"
108
- @worker.prepare
109
- silenced(2) do
110
- @worker.fork_one_job
111
- @templogger.wait_for_match(/Completed TestJobFork/m)
112
- @response_worker.prepare
113
- @response_worker.work_one_job
114
- end
115
- assert_equal 3, $worker_test_count
116
- end # enqueue
117
-
118
- it "should work for an async job" do
119
- @worker = @worker_class.new('bar.foo.2')
120
- TestAsyncJobForking.async(:queue => 'bar.foo.2').foo(3, 5)
121
- @worker.prepare
122
- silenced(4) do
123
- @worker.fork_one_job
124
- @templogger.wait_for_match(/Completed TestAsyncJobFork/m)
125
- @response_worker.prepare
126
- @response_worker.work_one_job
127
- end
128
- assert_equal 15, $worker_test_count
129
- end # async
130
-
131
- it "should fail quietly if there's an argument error" do
132
- Backburner.configure { |config| config.max_job_retries = 0 }
133
- @worker = @worker_class.new('bar.foo.3')
134
- @worker_class.enqueue TestJobForking, ["bam", "foo", "bar"], :queue => "bar.foo.3"
135
- @worker.prepare
136
- silenced(5) do
137
- @worker.fork_one_job
138
- @templogger.wait_for_match(/Finished TestJobFork.*attempt 1 of 1/m)
139
- end
140
- assert_match(/Exception ArgumentError/, @templogger.body)
141
- assert_equal 0, $worker_test_count
142
- end # fail, argument
143
-
144
- it "should support retrying jobs and burying" do
145
- Backburner.configure { |config| config.max_job_retries = 1; config.retry_delay = 0 }
146
- @worker = @worker_class.new('bar.foo.4')
147
- @worker_class.enqueue TestRetryJobForking, ["bam", "foo"], :queue => 'bar.foo.4'
148
- @worker.prepare
149
- silenced(4) do
150
- 2.times do
151
- $worker_test_count += 1
152
- @worker.fork_one_job
153
- end
154
- @templogger.wait_for_match(/Finished TestRetryJobFork.*attempt 2 of 2/m)
155
- @response_worker.prepare
156
- 2.times { @response_worker.work_one_job }
157
- end
158
- assert_equal 4, $worker_test_count
159
- assert_equal false, $worker_success
160
- end # retry, bury
161
-
162
- it "should support retrying jobs and succeeds" do
163
- Backburner.configure { |config| config.max_job_retries = 2; config.retry_delay = 0 }
164
- @worker = @worker_class.new('bar.foo.5')
165
- @worker_class.enqueue TestRetryJobForking, ["bam", "foo"], :queue => 'bar.foo.5'
166
- @worker.prepare
167
- silenced(4) do
168
- 3.times do
169
- $worker_test_count += 1
170
- @worker.fork_one_job
171
- end
172
- @templogger.wait_for_match(/Completed TestRetryJobFork/m)
173
- @response_worker.prepare
174
- 3.times { @response_worker.work_one_job }
175
- end
176
- assert_equal 6, $worker_test_count
177
- assert_equal true, $worker_success
178
- end # retrying, succeeds
179
-
180
- end # practical tests
181
- end