Commit 38c9612e authored by Sean McGivern's avatar Sean McGivern Committed by James Fargher

Mark Sidekiq queue selector as no longer experimental

We still support either the `--queue-selector` or
`--experimental-queue-selector` flag (not both at the same time,
though). We'll remove the 'experimental' variant on or after 14.0.
parent 9ae8443a
---
title: Mark Sidekiq queue selector as no longer experimental
merge_request: 46562
author:
type: changed
...@@ -110,29 +110,21 @@ you list: ...@@ -110,29 +110,21 @@ you list:
sudo gitlab-ctl reconfigure sudo gitlab-ctl reconfigure
``` ```
## Queue selector (experimental) ## Queue selector
> - [Introduced](https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/45) in [GitLab Starter](https://about.gitlab.com/pricing/) 12.8. > - [Introduced](https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/45) in [GitLab Starter](https://about.gitlab.com/pricing/) 12.8.
> - [Sidekiq cluster including queue selector moved](https://gitlab.com/groups/gitlab-com/gl-infra/-/epics/181) to GitLab [Core](https://about.gitlab.com/pricing/#self-managed) in GitLab 12.10. > - [Sidekiq cluster including queue selector moved](https://gitlab.com/groups/gitlab-com/gl-infra/-/epics/181) to GitLab [Core](https://about.gitlab.com/pricing/#self-managed) in GitLab 12.10.
> - [Marked as supported](https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/147) in GitLab [Core](https://about.gitlab.com/pricing/#self-managed) in GitLab 13.6. Renamed from `experimental_queue_selector` to `queue_selector`.
CAUTION: **Caution:** In addition to selecting queues by name, as above, the `queue_selector`
As this is marked as **experimental**, it is subject to change at any option allows queue groups to be selected in a more general way using
time, including **breaking backwards compatibility**. This is so that we the following components:
can react to changes we need for our GitLab.com deployment. We have a
tracking issue open to [remove the experimental
designation](https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/147)
from this feature; please comment there if you are interested in using
this in your own deployment.
In addition to selecting queues by name, as above, the
`experimental_queue_selector` option allows queue groups to be selected
in a more general way using the following components:
- Attributes that can be selected. - Attributes that can be selected.
- Operators used to construct a query. - Operators used to construct a query.
When `experimental_queue_selector` is set, all `queue_groups` must be in When `queue_selector` is set, all `queue_groups` must be in the queue
the queue selector syntax. selector syntax.
### Available attributes ### Available attributes
...@@ -140,8 +132,7 @@ the queue selector syntax. ...@@ -140,8 +132,7 @@ the queue selector syntax.
From the [list of all available From the [list of all available
attributes](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/workers/all_queues.yml), attributes](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/workers/all_queues.yml),
`experimental_queue_selector` allows selecting of queues by the `queue_selector` allows selecting of queues by the following attributes:
following attributes:
- `feature_category` - the [GitLab feature - `feature_category` - the [GitLab feature
category](https://about.gitlab.com/direction/maturity/#category-maturity) the category](https://about.gitlab.com/direction/maturity/#category-maturity) the
...@@ -173,8 +164,8 @@ neither of those tags. ...@@ -173,8 +164,8 @@ neither of those tags.
### Available operators ### Available operators
`experimental_queue_selector` supports the following operators, listed `queue_selector` supports the following operators, listed from highest
from highest to lowest precedence: to lowest precedence:
- `|` - the logical OR operator. For example, `query_a|query_b` (where `query_a` - `|` - the logical OR operator. For example, `query_a|query_b` (where `query_a`
and `query_b` are queries made up of the other operators here) will include and `query_b` are queries made up of the other operators here) will include
...@@ -205,7 +196,7 @@ In `/etc/gitlab/gitlab.rb`: ...@@ -205,7 +196,7 @@ In `/etc/gitlab/gitlab.rb`:
```ruby ```ruby
sidekiq['enable'] = true sidekiq['enable'] = true
sidekiq['experimental_queue_selector'] = true sidekiq['queue_selector'] = true
sidekiq['queue_groups'] = [ sidekiq['queue_groups'] = [
# Run all non-CPU-bound queues that are high urgency # Run all non-CPU-bound queues that are high urgency
'resource_boundary!=cpu&urgency=high', 'resource_boundary!=cpu&urgency=high',
...@@ -234,7 +225,7 @@ All of the aforementioned configuration options for `sidekiq` ...@@ -234,7 +225,7 @@ All of the aforementioned configuration options for `sidekiq`
are available. By default, they will be configured as follows: are available. By default, they will be configured as follows:
```ruby ```ruby
sidekiq['experimental_queue_selector'] = false sidekiq['queue_selector'] = false
sidekiq['interval'] = nil sidekiq['interval'] = nil
sidekiq['max_concurrency'] = 50 sidekiq['max_concurrency'] = 50
sidekiq['min_concurrency'] = nil sidekiq['min_concurrency'] = nil
......
...@@ -47,16 +47,24 @@ module Gitlab ...@@ -47,16 +47,24 @@ module Gitlab
option_parser.parse!(argv) option_parser.parse!(argv)
# Remove with https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/646
if @queue_selector && @experimental_queue_selector
raise CommandError,
'You cannot specify --queue-selector and --experimental-queue-selector together'
end
all_queues = SidekiqConfig::CliMethods.all_queues(@rails_path) all_queues = SidekiqConfig::CliMethods.all_queues(@rails_path)
queue_names = SidekiqConfig::CliMethods.worker_queues(@rails_path) queue_names = SidekiqConfig::CliMethods.worker_queues(@rails_path)
queue_groups = argv.map do |queues| queue_groups = argv.map do |queues|
next queue_names if queues == '*' next queue_names if queues == '*'
# When using the experimental queue query syntax, we treat # When using the queue query syntax, we treat each queue group
# each queue group as a worker attribute query, and resolve # as a worker attribute query, and resolve the queues for the
# the queues for the queue group using this query. # queue group using this query.
if @experimental_queue_selector
# Simplify with https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/646
if @queue_selector || @experimental_queue_selector
SidekiqConfig::CliMethods.query_workers(queues, all_queues) SidekiqConfig::CliMethods.query_workers(queues, all_queues)
else else
SidekiqConfig::CliMethods.expand_queues(queues.split(','), queue_names) SidekiqConfig::CliMethods.expand_queues(queues.split(','), queue_names)
...@@ -182,7 +190,12 @@ module Gitlab ...@@ -182,7 +190,12 @@ module Gitlab
@rails_path = path @rails_path = path
end end
opt.on('--experimental-queue-selector', 'EXPERIMENTAL: Run workers based on the provided selector') do |experimental_queue_selector| opt.on('--queue-selector', 'Run workers based on the provided selector') do |queue_selector|
@queue_selector = queue_selector
end
# Remove with https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/646
opt.on('--experimental-queue-selector', 'DEPRECATED: use --queue-selector-instead') do |experimental_queue_selector|
@experimental_queue_selector = experimental_queue_selector @experimental_queue_selector = experimental_queue_selector
end end
......
...@@ -9,6 +9,8 @@ RSpec.describe 'bin/sidekiq-cluster' do ...@@ -9,6 +9,8 @@ RSpec.describe 'bin/sidekiq-cluster' do
context 'when selecting some queues and excluding others' do context 'when selecting some queues and excluding others' do
where(:args, :included, :excluded) do where(:args, :included, :excluded) do
%w[--negate cronjob] | '-qdefault,1' | '-qcronjob,1' %w[--negate cronjob] | '-qdefault,1' | '-qcronjob,1'
%w[--queue-selector resource_boundary=cpu] | '-qupdate_merge_requests,1' | '-qdefault,1'
# Remove with https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/646
%w[--experimental-queue-selector resource_boundary=cpu] | '-qupdate_merge_requests,1' | '-qdefault,1' %w[--experimental-queue-selector resource_boundary=cpu] | '-qupdate_merge_requests,1' | '-qdefault,1'
end end
...@@ -29,6 +31,8 @@ RSpec.describe 'bin/sidekiq-cluster' do ...@@ -29,6 +31,8 @@ RSpec.describe 'bin/sidekiq-cluster' do
context 'when selecting all queues' do context 'when selecting all queues' do
[ [
%w[*], %w[*],
%w[--queue-selector *],
# Remove with https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/646
%w[--experimental-queue-selector *] %w[--experimental-queue-selector *]
].each do |args| ].each do |args|
it "runs successfully with `#{args}`", :aggregate_failures do it "runs successfully with `#{args}`", :aggregate_failures do
......
...@@ -108,101 +108,114 @@ RSpec.describe Gitlab::SidekiqCluster::CLI do ...@@ -108,101 +108,114 @@ RSpec.describe Gitlab::SidekiqCluster::CLI do
end end
end end
context 'with --experimental-queue-selector' do # Remove with https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/646
where do context 'with --queue-selector and --experimental-queue-selector' do
{ it 'errors' do
'memory-bound queues' => { expect(Gitlab::SidekiqCluster).not_to receive(:start)
query: 'resource_boundary=memory',
included_queues: %w(project_export), expect { cli.run(%w(--queue-selector name=foo --experimental-queue-selector name=bar)) }
excluded_queues: %w(merge) .to raise_error(described_class::CommandError)
},
'memory- or CPU-bound queues' => {
query: 'resource_boundary=memory,cpu',
included_queues: %w(auto_merge:auto_merge_process project_export),
excluded_queues: %w(merge)
},
'high urgency CI queues' => {
query: 'feature_category=continuous_integration&urgency=high',
included_queues: %w(pipeline_cache:expire_job_cache pipeline_cache:expire_pipeline_cache),
excluded_queues: %w(merge)
},
'CPU-bound high urgency CI queues' => {
query: 'feature_category=continuous_integration&urgency=high&resource_boundary=cpu',
included_queues: %w(pipeline_cache:expire_pipeline_cache),
excluded_queues: %w(pipeline_cache:expire_job_cache merge)
},
'CPU-bound high urgency non-CI queues' => {
query: 'feature_category!=continuous_integration&urgency=high&resource_boundary=cpu',
included_queues: %w(new_issue),
excluded_queues: %w(pipeline_cache:expire_pipeline_cache)
},
'CI and SCM queues' => {
query: 'feature_category=continuous_integration|feature_category=source_code_management',
included_queues: %w(pipeline_cache:expire_job_cache merge),
excluded_queues: %w(mailers)
}
}
end end
end
with_them do # Simplify with https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/646
it 'expands queues by attributes' do ['--queue-selector', '--experimental-queue-selector'].each do |flag|
expect(Gitlab::SidekiqCluster).to receive(:start) do |queues, opts| context "with #{flag}" do
expect(opts).to eq(default_options) where do
expect(queues.first).to include(*included_queues) {
expect(queues.first).not_to include(*excluded_queues) 'memory-bound queues' => {
query: 'resource_boundary=memory',
included_queues: %w(project_export),
excluded_queues: %w(merge)
},
'memory- or CPU-bound queues' => {
query: 'resource_boundary=memory,cpu',
included_queues: %w(auto_merge:auto_merge_process project_export),
excluded_queues: %w(merge)
},
'high urgency CI queues' => {
query: 'feature_category=continuous_integration&urgency=high',
included_queues: %w(pipeline_cache:expire_job_cache pipeline_cache:expire_pipeline_cache),
excluded_queues: %w(merge)
},
'CPU-bound high urgency CI queues' => {
query: 'feature_category=continuous_integration&urgency=high&resource_boundary=cpu',
included_queues: %w(pipeline_cache:expire_pipeline_cache),
excluded_queues: %w(pipeline_cache:expire_job_cache merge)
},
'CPU-bound high urgency non-CI queues' => {
query: 'feature_category!=continuous_integration&urgency=high&resource_boundary=cpu',
included_queues: %w(new_issue),
excluded_queues: %w(pipeline_cache:expire_pipeline_cache)
},
'CI and SCM queues' => {
query: 'feature_category=continuous_integration|feature_category=source_code_management',
included_queues: %w(pipeline_cache:expire_job_cache merge),
excluded_queues: %w(mailers)
}
}
end
with_them do
it 'expands queues by attributes' do
expect(Gitlab::SidekiqCluster).to receive(:start) do |queues, opts|
expect(opts).to eq(default_options)
expect(queues.first).to include(*included_queues)
expect(queues.first).not_to include(*excluded_queues)
[]
end
[] cli.run(%W(#{flag} #{query}))
end end
cli.run(%W(--experimental-queue-selector #{query})) it 'works when negated' do
end expect(Gitlab::SidekiqCluster).to receive(:start) do |queues, opts|
expect(opts).to eq(default_options)
expect(queues.first).not_to include(*included_queues)
expect(queues.first).to include(*excluded_queues)
it 'works when negated' do []
expect(Gitlab::SidekiqCluster).to receive(:start) do |queues, opts| end
expect(opts).to eq(default_options)
expect(queues.first).not_to include(*included_queues)
expect(queues.first).to include(*excluded_queues)
[] cli.run(%W(--negate #{flag} #{query}))
end end
cli.run(%W(--negate --experimental-queue-selector #{query}))
end end
end
it 'expands multiple queue groups correctly' do it 'expands multiple queue groups correctly' do
expect(Gitlab::SidekiqCluster) expect(Gitlab::SidekiqCluster)
.to receive(:start) .to receive(:start)
.with([['chat_notification'], ['project_export']], default_options) .with([['chat_notification'], ['project_export']], default_options)
.and_return([]) .and_return([])
cli.run(%w(--experimental-queue-selector feature_category=chatops&has_external_dependencies=true resource_boundary=memory&feature_category=importers)) cli.run(%W(#{flag} feature_category=chatops&has_external_dependencies=true resource_boundary=memory&feature_category=importers))
end end
it 'allows the special * selector' do it 'allows the special * selector' do
worker_queues = %w(foo bar baz) worker_queues = %w(foo bar baz)
expect(Gitlab::SidekiqConfig::CliMethods) expect(Gitlab::SidekiqConfig::CliMethods)
.to receive(:worker_queues).and_return(worker_queues) .to receive(:worker_queues).and_return(worker_queues)
expect(Gitlab::SidekiqCluster) expect(Gitlab::SidekiqCluster)
.to receive(:start).with([worker_queues], default_options) .to receive(:start).with([worker_queues], default_options)
cli.run(%w(--experimental-queue-selector *)) cli.run(%W(#{flag} *))
end end
it 'errors when the selector matches no queues' do it 'errors when the selector matches no queues' do
expect(Gitlab::SidekiqCluster).not_to receive(:start) expect(Gitlab::SidekiqCluster).not_to receive(:start)
expect { cli.run(%w(--experimental-queue-selector has_external_dependencies=true&has_external_dependencies=false)) } expect { cli.run(%W(#{flag} has_external_dependencies=true&has_external_dependencies=false)) }
.to raise_error(described_class::CommandError) .to raise_error(described_class::CommandError)
end end
it 'errors on an invalid query multiple queue groups correctly' do it 'errors on an invalid query multiple queue groups correctly' do
expect(Gitlab::SidekiqCluster).not_to receive(:start) expect(Gitlab::SidekiqCluster).not_to receive(:start)
expect { cli.run(%w(--experimental-queue-selector unknown_field=chatops)) } expect { cli.run(%W(#{flag} unknown_field=chatops)) }
.to raise_error(Gitlab::SidekiqConfig::CliMethods::QueryError) .to raise_error(Gitlab::SidekiqConfig::CliMethods::QueryError)
end
end end
end end
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment