From c31f493e8ae8aefc3e14cd8f18eaba8dfb1a3f73 Mon Sep 17 00:00:00 2001 From: gremerritt Date: Thu, 21 Sep 2023 14:44:17 -0400 Subject: [PATCH] Benchmark --- lib/delayed/job_groups/job_group.rb | 3 ++ spec/delayed/job_groups/job_group_spec.rb | 41 +++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/lib/delayed/job_groups/job_group.rb b/lib/delayed/job_groups/job_group.rb index 77c980b..39bfce7 100644 --- a/lib/delayed/job_groups/job_group.rb +++ b/lib/delayed/job_groups/job_group.rb @@ -24,6 +24,9 @@ class JobGroup < ActiveRecord::Base scope :ready, -> { where(queueing_complete: true, blocked: false) } scope :with_no_open_jobs, -> { left_joins(:active_jobs).group(:id).having('count(delayed_jobs.id) == 0') } + scope :with_no_open_jobs_exists, -> do + where("not exists (#{Delayed::Job.where('delayed_jobs.job_group_id = delayed_job_groups.id').to_sql})") + end def mark_queueing_complete with_lock do diff --git a/spec/delayed/job_groups/job_group_spec.rb b/spec/delayed/job_groups/job_group_spec.rb index 92da6b3..f94c40b 100644 --- a/spec/delayed/job_groups/job_group_spec.rb +++ b/spec/delayed/job_groups/job_group_spec.rb @@ -46,6 +46,47 @@ expect(described_class.with_no_open_jobs).to match_array(job_group_without_jobs) end end + + describe "with_no_open_jobs_exists" do + let!(:job_group_with_jobs) { create(:delayed_job).job_group } + let!(:job_group_without_jobs) { subject } + + it "returns groups with no jobs" do + expect(described_class.with_no_open_jobs_exists).to match_array(job_group_without_jobs) + end + end + + describe "perf" do + let(:iterations) { 1000 } + let(:num_job_groups) { 1_000 } + + before do + ActiveSupport::Deprecation.silenced = true + require 'benchmark' + @zeros = 0 + + num_job_groups.times do |i| + puts "Creating job group # #{i}" if i % 100 == 0 + job_group = create(:job_group) + n = Integer(rand.round(1) * 100) + if n.zero? + @zeros += 1 + else + create_list(:delayed_job, n, job_group: job_group) + end + end + end + + it "benchmark" do + Benchmark.bm do |bench| + bench.report(:having) { iterations.times { described_class.with_no_open_jobs.to_a } } + bench.report(:exists) { iterations.times { described_class.with_no_open_jobs_exists.to_a } } + end + + expect(described_class.with_no_open_jobs.to_a.size).to eq @zeros + expect(described_class.with_no_open_jobs_exists.to_a.size).to eq @zeros + end + end end shared_examples "the job group was completed" do