|
| 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