From 45af39fc59a80dca7f4016fe10ba9f8af09ccd79 Mon Sep 17 00:00:00 2001 From: Gregorius Marco <gmarco@gitlab.com> Date: Mon, 6 May 2024 18:35:07 +0000 Subject: [PATCH] Remove min and max_concurrency option in Sidekiq cluster Deprecated in https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/2760 in favor of the new `concurrency` option. Changelog: removed --- sidekiq_cluster/cli.rb | 21 +-------- sidekiq_cluster/sidekiq_cluster.rb | 20 ++------- spec/commands/sidekiq_cluster/cli_spec.rb | 46 ++------------------ spec/sidekiq_cluster/sidekiq_cluster_spec.rb | 40 +++-------------- 4 files changed, 13 insertions(+), 114 deletions(-) diff --git a/sidekiq_cluster/cli.rb b/sidekiq_cluster/cli.rb index 1f02d9b39c0a1..e3045c1776833 100644 --- a/sidekiq_cluster/cli.rb +++ b/sidekiq_cluster/cli.rb @@ -38,10 +38,7 @@ class CLI def initialize(log_output = $stderr) # https://github.com/mperham/sidekiq/wiki/Advanced-Options#concurrency # https://ruby.social/@getajobmike/109326475545816363 - @max_concurrency = 20 - @min_concurrency = 0 - # TODO: to be set to 20 once max_concurrency and min_concurrency is removed https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/2760 - @concurrency = 0 + @concurrency = 20 @environment = ENV['RAILS_ENV'] || 'development' @metrics_dir = ENV["prometheus_multiproc_dir"] || File.absolute_path("tmp/prometheus_multiproc_dir/sidekiq") @pid = nil @@ -91,12 +88,6 @@ def run(argv = ARGV) 'No queues found, you must select at least one queue' end - if routing_rules.empty? - # setting min_concurrency equal to max_concurrency so that the concurrency eventually - # is set to 20 (default value) instead of based on the number of queues, which is only 2+1 in this case. - @min_concurrency = @min_concurrency == 0 ? @max_concurrency : @min_concurrency - end - if @list_queues puts queue_groups.map(&:sort) # rubocop:disable Rails/Output @@ -120,8 +111,6 @@ def start_and_supervise_workers(queue_groups) queue_groups, env: @environment, directory: @rails_path, - max_concurrency: @max_concurrency, - min_concurrency: @min_concurrency, concurrency: @concurrency, dryrun: @dryrun, timeout: @soft_timeout_seconds @@ -214,14 +203,6 @@ def option_parser @concurrency = int.to_i end - opt.on('-m', '--max-concurrency INT', 'Maximum threads to use with Sidekiq (default: 20, 0 to disable)') do |int| - @max_concurrency = int.to_i - end - - opt.on('--min-concurrency INT', 'Minimum threads to use with Sidekiq (default: 0)') do |int| - @min_concurrency = int.to_i - end - opt.on('-e', '--environment ENV', 'The application environment') do |env| @environment = env end diff --git a/sidekiq_cluster/sidekiq_cluster.rb b/sidekiq_cluster/sidekiq_cluster.rb index 579bb0264138b..2ad6efbc3afa3 100644 --- a/sidekiq_cluster/sidekiq_cluster.rb +++ b/sidekiq_cluster/sidekiq_cluster.rb @@ -36,12 +36,10 @@ module SidekiqCluster # # Returns an Array containing the waiter threads (from Process.detach) of # the started processes. - def self.start(queues, env: :development, directory: Dir.pwd, max_concurrency: 20, min_concurrency: 0, concurrency: 0, timeout: DEFAULT_SOFT_TIMEOUT_SECONDS, dryrun: false) + def self.start(queues, env: :development, directory: Dir.pwd, concurrency: 20, timeout: DEFAULT_SOFT_TIMEOUT_SECONDS, dryrun: false) queues.map.with_index do |pair, index| start_sidekiq(pair, env: env, directory: directory, - max_concurrency: max_concurrency, - min_concurrency: min_concurrency, concurrency: concurrency, worker_id: index, timeout: timeout, @@ -52,13 +50,11 @@ def self.start(queues, env: :development, directory: Dir.pwd, max_concurrency: 2 # Starts a Sidekiq process that processes _only_ the given queues. # # Returns the PID of the started process. - # rubocop: disable Metrics/ParameterLists -- max_concurrency and min_concurrency will be removed in 17.0 - def self.start_sidekiq(queues, env:, directory:, max_concurrency:, min_concurrency:, concurrency:, worker_id:, timeout:, dryrun:) - # rubocop: enable Metrics/ParameterLists + def self.start_sidekiq(queues, env:, directory:, concurrency:, worker_id:, timeout:, dryrun:) counts = count_by_queue(queues) cmd = %w[bundle exec sidekiq] - cmd << "-c#{self.concurrency(queues, min_concurrency, max_concurrency, concurrency)}" + cmd << "-c#{concurrency}" cmd << "-e#{env}" cmd << "-t#{timeout}" cmd << "-gqueues:#{proc_details(counts)}" @@ -103,15 +99,5 @@ def self.proc_details(counts) end end.join(',') end - - def self.concurrency(queues, min_concurrency, max_concurrency, concurrency) - return concurrency if concurrency > 0 - - concurrency_from_queues = queues.length + 1 - max = max_concurrency > 0 ? max_concurrency : concurrency_from_queues - min = [min_concurrency, max].min - - concurrency_from_queues.clamp(min, max) - end end end diff --git a/spec/commands/sidekiq_cluster/cli_spec.rb b/spec/commands/sidekiq_cluster/cli_spec.rb index 43eba23dd5828..8be89d7a0acfc 100644 --- a/spec/commands/sidekiq_cluster/cli_spec.rb +++ b/spec/commands/sidekiq_cluster/cli_spec.rb @@ -12,7 +12,7 @@ let(:cli) { described_class.new('/dev/null') } let(:timeout) { Gitlab::SidekiqCluster::DEFAULT_SOFT_TIMEOUT_SECONDS } let(:default_options) do - { env: 'test', directory: Dir.pwd, max_concurrency: 20, min_concurrency: 0, dryrun: false, timeout: timeout, concurrency: 0 } + { env: 'test', directory: Dir.pwd, dryrun: false, timeout: timeout, concurrency: 20 } end let(:sidekiq_exporter_enabled) { false } @@ -120,28 +120,6 @@ end end - context 'with --max-concurrency flag' do - it 'starts Sidekiq workers for specified queues with a max concurrency' do - expected_queues = [%w[foo bar baz], %w[solo]] - expect(Gitlab::SidekiqCluster).to receive(:start) - .with(expected_queues, default_options.merge(max_concurrency: 2)) - .and_return([]) - - cli.run(%w[foo,bar,baz solo -m 2]) - end - end - - context 'with --min-concurrency flag' do - it 'starts Sidekiq workers for specified queues with a min concurrency' do - expected_queues = [%w[foo bar baz], %w[solo]] - expect(Gitlab::SidekiqCluster).to receive(:start) - .with(expected_queues, default_options.merge(min_concurrency: 2)) - .and_return([]) - - cli.run(%w[foo,bar,baz solo --min-concurrency 2]) - end - end - context 'with --concurrency flag' do it 'starts Sidekiq workers for specified queues with the fixed concurrency' do expected_queues = [%w[foo bar baz], %w[solo]] @@ -203,8 +181,7 @@ expect { cli.run(%w[foo]) }.not_to raise_error end - it "starts Sidekiq workers with DEFAULT_QUEUES and min_concurrency = max_concurrency" do - default_options[:min_concurrency] = default_options[:max_concurrency] + it "starts Sidekiq workers with DEFAULT_QUEUES" do expect(Gitlab::SidekiqCluster).to receive(:start) .with([described_class::DEFAULT_QUEUES], default_options) .and_return([]) @@ -214,7 +191,6 @@ context 'with multi argument queues' do it 'starts with multiple DEFAULT_QUEUES' do - default_options[:min_concurrency] = default_options[:max_concurrency] expected_queues = [%w[default mailers], %w[default mailers]] expect(Gitlab::SidekiqCluster) @@ -230,8 +206,7 @@ stub_config(sidekiq: { routing_rules: [] }) end - it "starts Sidekiq workers with DEFAULT_QUEUES and min_concurrency = max_concurrency" do - default_options[:min_concurrency] = default_options[:max_concurrency] + it "starts Sidekiq workers with DEFAULT_QUEUES" do expect(Gitlab::SidekiqCluster).to receive(:start) .with([described_class::DEFAULT_QUEUES], default_options) .and_return([]) @@ -240,8 +215,7 @@ end context "with 4 wildcard * as argument" do - it "starts 4 Sidekiq workers all with DEFAULT_QUEUES and min_concurrency = max_concurrency" do - default_options[:min_concurrency] = default_options[:max_concurrency] + it "starts 4 Sidekiq workers all with DEFAULT_QUEUES" do expect(Gitlab::SidekiqCluster).to receive(:start) .with([described_class::DEFAULT_QUEUES] * 4, default_options) .and_return([]) @@ -249,18 +223,6 @@ cli.run(%w[* * * *]) end end - - context "with min-concurrency flag" do - it "starts Sidekiq workers with DEFAULT_QUEUES and min_concurrency as specified" do - options = default_options.dup - options[:min_concurrency] = 10 - expect(Gitlab::SidekiqCluster).to receive(:start) - .with([described_class::DEFAULT_QUEUES] * 4, options) - .and_return([]) - - cli.run(%w[* * * * --min-concurrency 10]) - end - end end end diff --git a/spec/sidekiq_cluster/sidekiq_cluster_spec.rb b/spec/sidekiq_cluster/sidekiq_cluster_spec.rb index d79636366641a..3ce1117a34e91 100644 --- a/spec/sidekiq_cluster/sidekiq_cluster_spec.rb +++ b/spec/sidekiq_cluster/sidekiq_cluster_spec.rb @@ -19,7 +19,7 @@ "ENABLE_SIDEKIQ_CLUSTER" => "1", "SIDEKIQ_WORKER_ID" => "0" }, - "bundle", "exec", "sidekiq", "-c10", "-eproduction", "-t25", "-gqueues:foo", "-rfoo/bar", "-qfoo,1", process_options + "bundle", "exec", "sidekiq", "-c20", "-eproduction", "-t25", "-gqueues:foo", "-rfoo/bar", "-qfoo,1", process_options ).and_return(1) expect(Process).to receive(:detach).ordered.with(1) @@ -27,23 +27,21 @@ "ENABLE_SIDEKIQ_CLUSTER" => "1", "SIDEKIQ_WORKER_ID" => "1" }, - "bundle", "exec", "sidekiq", "-c10", "-eproduction", "-t25", "-gqueues:bar,baz", "-rfoo/bar", "-qbar,1", "-qbaz,1", process_options + "bundle", "exec", "sidekiq", "-c20", "-eproduction", "-t25", "-gqueues:bar,baz", "-rfoo/bar", "-qbar,1", "-qbaz,1", process_options ).and_return(2) expect(Process).to receive(:detach).ordered.with(2) - described_class.start([%w[foo], %w[bar baz]], env: :production, directory: 'foo/bar', max_concurrency: 20, min_concurrency: 10) + described_class.start([%w[foo], %w[bar baz]], env: :production, directory: 'foo/bar', concurrency: 20) end it 'starts Sidekiq with the given queues and sensible default options' do expected_options = { env: :development, directory: an_instance_of(String), - max_concurrency: 20, - min_concurrency: 0, worker_id: an_instance_of(Integer), timeout: 25, dryrun: false, - concurrency: 0 + concurrency: 20 } expect(described_class).to receive(:start_sidekiq).ordered.with(%w[foo bar baz], expected_options) @@ -56,7 +54,7 @@ describe '.start_sidekiq' do let(:first_worker_id) { 0 } let(:options) do - { env: :production, directory: 'foo/bar', max_concurrency: 20, min_concurrency: 0, worker_id: first_worker_id, timeout: 10, dryrun: false, concurrency: 0 } + { env: :production, directory: 'foo/bar', worker_id: first_worker_id, timeout: 10, dryrun: false, concurrency: 20 } end let(:env) { { "ENABLE_SIDEKIQ_CLUSTER" => "1", "SIDEKIQ_WORKER_ID" => first_worker_id.to_s } } @@ -99,32 +97,4 @@ expect(described_class.count_by_queue(queues)).to eq(%w[foo] => 2, %w[bar baz] => 1) end end - - describe '.concurrency' do - using RSpec::Parameterized::TableSyntax - - where(:queue_count, :min, :max, :fixed_concurrency, :expected) do - # without fixed concurrency - 2 | 0 | 0 | 0 | 3 # No min or max specified - 2 | 0 | 9 | 0 | 3 # No min specified, value < max - 2 | 1 | 4 | 0 | 3 # Value between min and max - 2 | 4 | 5 | 0 | 4 # Value below range - 5 | 2 | 3 | 0 | 3 # Value above range - 2 | 1 | 1 | 0 | 1 # Value above explicit setting (min == max) - 0 | 3 | 3 | 0 | 3 # Value below explicit setting (min == max) - 1 | 4 | 3 | 0 | 3 # Min greater than max - - # with fixed concurrency, expected always equal to fixed_concurrency - 1 | 0 | 20 | 20 | 20 - 1 | 0 | 20 | 10 | 10 - 1 | 20 | 20 | 10 | 10 - 5 | 0 | 0 | 10 | 10 - end - - with_them do - let(:queues) { Array.new(queue_count) } - - it { expect(described_class.concurrency(queues, min, max, fixed_concurrency)).to eq(expected) } - end - end end -- GitLab