Skip to content

Commit 1ef7f38

Browse files
committed
Initial batch lifecycle tests
* Attach success jobs to the parent batch, not to the current batch (which has already finished at this point)
1 parent 5004556 commit 1ef7f38

File tree

2 files changed

+84
-1
lines changed

2 files changed

+84
-1
lines changed

app/models/solid_queue/job_batch.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ def perform_completion_job(job_field, attrs)
148148
active_job = ActiveJob::Base.deserialize(send(job_field))
149149
active_job.send(:deserialize_arguments_if_needed)
150150
active_job.arguments = [ self ] + Array.wrap(active_job.arguments)
151-
self.class.wrap_in_batch_context(id) do
151+
self.class.wrap_in_batch_context(parent_job_batch_id || self.class.current_batch_id) do
152152
ActiveJob.perform_all_later([ active_job ])
153153
end
154154
active_job.provider_job_id = Job.find_by(active_job_id: active_job.job_id).id
+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# frozen_string_literal: true
2+
3+
require "test_helper"
4+
5+
class BatchLifecycleTest < ActiveSupport::TestCase
6+
setup do
7+
@worker = SolidQueue::Worker.new(queues: "background", threads: 3)
8+
@dispatcher = SolidQueue::Dispatcher.new(batch_size: 10, polling_interval: 0.2)
9+
end
10+
11+
teardown do
12+
@worker.stop
13+
@dispatcher.stop
14+
15+
JobBuffer.clear
16+
17+
SolidQueue::Job.destroy_all
18+
SolidQueue::JobBatch.destroy_all
19+
end
20+
21+
class BatchOnSuccessJob < ApplicationJob
22+
queue_as :background
23+
24+
def perform(batch, custom_message = "")
25+
JobBuffer.add "#{custom_message}: #{batch.jobs.size} jobs succeeded!"
26+
end
27+
end
28+
29+
class AddsMoreJobsJob < ApplicationJob
30+
queue_as :background
31+
32+
def perform
33+
batch.enqueue do
34+
AddToBufferJob.perform_later "added from inside 1"
35+
AddToBufferJob.perform_later "added from inside 2"
36+
SolidQueue::JobBatch.enqueue do
37+
AddToBufferJob.perform_later "added from inside 3"
38+
end
39+
end
40+
end
41+
end
42+
43+
test "nested batches finish from the inside out" do
44+
batch2 = batch3 = batch4 = nil
45+
batch1 = SolidQueue::JobBatch.enqueue(on_success: BatchOnSuccessJob.new("3")) do
46+
batch2 = SolidQueue::JobBatch.enqueue(on_success: BatchOnSuccessJob.new("2")) do
47+
batch3 = SolidQueue::JobBatch.enqueue(on_success: BatchOnSuccessJob.new("1")) { }
48+
batch4 = SolidQueue::JobBatch.enqueue(on_success: BatchOnSuccessJob.new("1.1")) { }
49+
end
50+
end
51+
52+
@dispatcher.start
53+
@worker.start
54+
55+
wait_for_job_batches_to_finish_for(2.seconds)
56+
wait_for_jobs_to_finish_for(2.seconds)
57+
58+
assert_equal [ "1: 0 jobs succeeded!", "1.1: 0 jobs succeeded!", "2: 2 jobs succeeded!", "3: 1 jobs succeeded!" ], JobBuffer.values
59+
assert_equal 4, SolidQueue::JobBatch.finished.count
60+
assert_equal batch1.reload.finished_at > batch2.reload.finished_at, true
61+
assert_equal batch2.finished_at > batch3.reload.finished_at, true
62+
assert_equal batch2.finished_at > batch4.reload.finished_at, true
63+
end
64+
65+
test "all jobs are run, including jobs enqueued inside of other jobs" do
66+
SolidQueue::JobBatch.enqueue do
67+
AddToBufferJob.perform_later "hey"
68+
SolidQueue::JobBatch.enqueue do
69+
AddToBufferJob.perform_later "ho"
70+
AddsMoreJobsJob.perform_later
71+
end
72+
end
73+
74+
@dispatcher.start
75+
@worker.start
76+
77+
wait_for_job_batches_to_finish_for(2.seconds)
78+
wait_for_jobs_to_finish_for(2.seconds)
79+
80+
assert_equal [ "added from inside 1", "added from inside 2", "added from inside 3", "hey", "ho" ], JobBuffer.values.sort
81+
assert_equal 3, SolidQueue::JobBatch.finished.count
82+
end
83+
end

0 commit comments

Comments
 (0)