Commit d51072d0 authored by Heinrich Lee Yu's avatar Heinrich Lee Yu

Merge branch 'add-worker-parameter-to-queues-api' into 'master'

Add worker_class argument to Sidekiq queues APIs

See merge request gitlab-org/gitlab!70179
parents d537f28a 63979ec0
...@@ -8,13 +8,18 @@ module Mutations ...@@ -8,13 +8,18 @@ module Mutations
ADMIN_MESSAGE = 'You must be an admin to use this mutation' ADMIN_MESSAGE = 'You must be an admin to use this mutation'
Gitlab::ApplicationContext::KNOWN_KEYS.each do |key| ::Gitlab::ApplicationContext::KNOWN_KEYS.each do |key|
argument key, argument key,
GraphQL::Types::String, GraphQL::Types::String,
required: false, required: false,
description: "Delete jobs matching #{key} in the context metadata" description: "Delete jobs matching #{key} in the context metadata."
end end
argument ::Gitlab::SidekiqQueue::WORKER_KEY,
GraphQL::Types::String,
required: false,
description: 'Delete jobs with the given worker class.'
argument :queue_name, argument :queue_name,
GraphQL::Types::String, GraphQL::Types::String,
required: true, required: true,
......
...@@ -28,7 +28,7 @@ DELETE /admin/sidekiq/queues/:queue_name ...@@ -28,7 +28,7 @@ DELETE /admin/sidekiq/queues/:queue_name
``` ```
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | -------------- | -------- | ----------- | |---------------------|--------|----------|----------------------------------------------------------------------------------------------------------------------------------------------|
| `queue_name` | string | yes | The name of the queue to delete jobs from | | `queue_name` | string | yes | The name of the queue to delete jobs from |
| `user` | string | no | The username of the user who scheduled the jobs | | `user` | string | no | The username of the user who scheduled the jobs |
| `project` | string | no | The full path of the project where the jobs were scheduled from | | `project` | string | no | The full path of the project where the jobs were scheduled from |
...@@ -36,6 +36,7 @@ DELETE /admin/sidekiq/queues/:queue_name ...@@ -36,6 +36,7 @@ DELETE /admin/sidekiq/queues/:queue_name
| `subscription_plan` | string | no | The subscription plan of the root namespace (GitLab.com only) | | `subscription_plan` | string | no | The subscription plan of the root namespace (GitLab.com only) |
| `caller_id` | string | no | The endpoint or background job that schedule the job (for example: `ProjectsController#create`, `/api/:version/projects/:id`, `PostReceive`) | | `caller_id` | string | no | The endpoint or background job that schedule the job (for example: `ProjectsController#create`, `/api/:version/projects/:id`, `PostReceive`) |
| `feature_category` | string | no | The feature category of the background job (for example: `issue_tracking` or `code_review`) | | `feature_category` | string | no | The feature category of the background job (for example: `issue_tracking` or `code_review`) |
| `worker_class` | string | no | The class of the background job worker (for example: `PostReceive` or `MergeWorker`) |
At least one attribute, other than `queue_name`, is required. At least one attribute, other than `queue_name`, is required.
......
...@@ -563,6 +563,7 @@ Input type: `AdminSidekiqQueuesDeleteJobsInput` ...@@ -563,6 +563,7 @@ Input type: `AdminSidekiqQueuesDeleteJobsInput`
| <a id="mutationadminsidekiqqueuesdeletejobsrootnamespace"></a>`rootNamespace` | [`String`](#string) | Delete jobs matching root_namespace in the context metadata. | | <a id="mutationadminsidekiqqueuesdeletejobsrootnamespace"></a>`rootNamespace` | [`String`](#string) | Delete jobs matching root_namespace in the context metadata. |
| <a id="mutationadminsidekiqqueuesdeletejobssubscriptionplan"></a>`subscriptionPlan` | [`String`](#string) | Delete jobs matching subscription_plan in the context metadata. | | <a id="mutationadminsidekiqqueuesdeletejobssubscriptionplan"></a>`subscriptionPlan` | [`String`](#string) | Delete jobs matching subscription_plan in the context metadata. |
| <a id="mutationadminsidekiqqueuesdeletejobsuser"></a>`user` | [`String`](#string) | Delete jobs matching user in the context metadata. | | <a id="mutationadminsidekiqqueuesdeletejobsuser"></a>`user` | [`String`](#string) | Delete jobs matching user in the context metadata. |
| <a id="mutationadminsidekiqqueuesdeletejobsworkerclass"></a>`workerClass` | [`String`](#string) | Delete jobs with the given worker class. |
#### Fields #### Fields
......
...@@ -12,11 +12,11 @@ module API ...@@ -12,11 +12,11 @@ module API
namespace 'queues' do namespace 'queues' do
desc 'Drop jobs matching the given metadata from the Sidekiq queue' desc 'Drop jobs matching the given metadata from the Sidekiq queue'
params do params do
Gitlab::ApplicationContext::KNOWN_KEYS.each do |key| Gitlab::SidekiqQueue::ALLOWED_KEYS.each do |key|
optional key, type: String, allow_blank: false optional key, type: String, allow_blank: false
end end
at_least_one_of(*Gitlab::ApplicationContext::KNOWN_KEYS) at_least_one_of(*Gitlab::SidekiqQueue::ALLOWED_KEYS)
end end
delete ':queue_name' do delete ':queue_name' do
result = result =
......
...@@ -7,6 +7,9 @@ module Gitlab ...@@ -7,6 +7,9 @@ module Gitlab
NoMetadataError = Class.new(StandardError) NoMetadataError = Class.new(StandardError)
InvalidQueueError = Class.new(StandardError) InvalidQueueError = Class.new(StandardError)
WORKER_KEY = 'worker_class'
ALLOWED_KEYS = Gitlab::ApplicationContext::KNOWN_KEYS + [WORKER_KEY]
attr_reader :queue_name attr_reader :queue_name
def initialize(queue_name) def initialize(queue_name)
...@@ -21,8 +24,8 @@ module Gitlab ...@@ -21,8 +24,8 @@ module Gitlab
job_search_metadata = job_search_metadata =
search_metadata search_metadata
.stringify_keys .stringify_keys
.slice(*Gitlab::ApplicationContext::KNOWN_KEYS) .slice(*ALLOWED_KEYS)
.transform_keys { |key| "meta.#{key}" } .transform_keys(&method(:transform_key))
.compact .compact
raise NoMetadataError if job_search_metadata.empty? raise NoMetadataError if job_search_metadata.empty?
...@@ -49,6 +52,14 @@ module Gitlab ...@@ -49,6 +52,14 @@ module Gitlab
private private
def transform_key(key)
if Gitlab::ApplicationContext::KNOWN_KEYS.include?(key)
"meta.#{key}"
elsif key == WORKER_KEY
'class'
end
end
def queue def queue
strong_memoize(:queue) do strong_memoize(:queue) do
# Sidekiq::Queue.new always returns a queue, even if it doesn't # Sidekiq::Queue.new always returns a queue, even if it doesn't
......
...@@ -4,15 +4,15 @@ require 'spec_helper' ...@@ -4,15 +4,15 @@ require 'spec_helper'
RSpec.describe Gitlab::SidekiqQueue, :clean_gitlab_redis_queues do RSpec.describe Gitlab::SidekiqQueue, :clean_gitlab_redis_queues do
around do |example| around do |example|
Sidekiq::Queue.new('authorized_projects').clear Sidekiq::Queue.new('default').clear
Sidekiq::Testing.disable!(&example) Sidekiq::Testing.disable!(&example)
Sidekiq::Queue.new('authorized_projects').clear Sidekiq::Queue.new('default').clear
end end
def add_job(user, args) def add_job(args, user:, klass: 'AuthorizedProjectsWorker')
Sidekiq::Client.push( Sidekiq::Client.push(
'class' => 'AuthorizedProjectsWorker', 'class' => klass,
'queue' => 'authorized_projects', 'queue' => 'default',
'args' => args, 'args' => args,
'meta.user' => user.username 'meta.user' => user.username
) )
...@@ -20,13 +20,13 @@ RSpec.describe Gitlab::SidekiqQueue, :clean_gitlab_redis_queues do ...@@ -20,13 +20,13 @@ RSpec.describe Gitlab::SidekiqQueue, :clean_gitlab_redis_queues do
describe '#drop_jobs!' do describe '#drop_jobs!' do
shared_examples 'queue processing' do shared_examples 'queue processing' do
let(:sidekiq_queue) { described_class.new('authorized_projects') } let(:sidekiq_queue) { described_class.new('default') }
let_it_be(:sidekiq_queue_user) { create(:user) } let_it_be(:sidekiq_queue_user) { create(:user) }
before do before do
add_job(create(:user), [1]) add_job([1], user: create(:user))
add_job(sidekiq_queue_user, [2]) add_job([2], user: sidekiq_queue_user, klass: 'MergeWorker')
add_job(sidekiq_queue_user, [3]) add_job([3], user: sidekiq_queue_user)
end end
context 'when the queue is not processed in time' do context 'when the queue is not processed in time' do
...@@ -68,11 +68,19 @@ RSpec.describe Gitlab::SidekiqQueue, :clean_gitlab_redis_queues do ...@@ -68,11 +68,19 @@ RSpec.describe Gitlab::SidekiqQueue, :clean_gitlab_redis_queues do
end end
end end
context 'when there are jobs matching the class name' do
include_examples 'queue processing' do
let(:search_metadata) { { user: sidekiq_queue_user.username, worker_class: 'AuthorizedProjectsWorker' } }
let(:timeout_deleted) { 1 }
let(:no_timeout_deleted) { 1 }
end
end
context 'when there are no valid metadata keys passed' do context 'when there are no valid metadata keys passed' do
it 'raises NoMetadataError' do it 'raises NoMetadataError' do
add_job(create(:user), [1]) add_job([1], user: create(:user))
expect { described_class.new('authorized_projects').drop_jobs!({ username: 'sidekiq_queue_user' }, timeout: 1) } expect { described_class.new('default').drop_jobs!({ username: 'sidekiq_queue_user' }, timeout: 1) }
.to raise_error(described_class::NoMetadataError) .to raise_error(described_class::NoMetadataError)
end end
end end
......
...@@ -36,7 +36,7 @@ RSpec.describe API::Admin::Sidekiq, :clean_gitlab_redis_queues do ...@@ -36,7 +36,7 @@ RSpec.describe API::Admin::Sidekiq, :clean_gitlab_redis_queues do
add_job(admin, [2]) add_job(admin, [2])
add_job(create(:user), [3]) add_job(create(:user), [3])
delete api("/admin/sidekiq/queues/authorized_projects?user=#{admin.username}", admin) delete api("/admin/sidekiq/queues/authorized_projects?user=#{admin.username}&worker_class=AuthorizedProjectsWorker", admin)
expect(response).to have_gitlab_http_status(:ok) expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to eq('completed' => true, expect(json_response).to eq('completed' => true,
......
...@@ -9,7 +9,7 @@ RSpec.describe 'Deleting Sidekiq jobs', :clean_gitlab_redis_queues do ...@@ -9,7 +9,7 @@ RSpec.describe 'Deleting Sidekiq jobs', :clean_gitlab_redis_queues do
let(:queue) { 'authorized_projects' } let(:queue) { 'authorized_projects' }
let(:variables) { { user: admin.username, queue_name: queue } } let(:variables) { { user: admin.username, worker_class: 'AuthorizedProjectsWorker', queue_name: queue } }
let(:mutation) { graphql_mutation(:admin_sidekiq_queues_delete_jobs, variables) } let(:mutation) { graphql_mutation(:admin_sidekiq_queues_delete_jobs, variables) }
def mutation_response def mutation_response
......
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