Commit 43e8687d authored by Dmitry Gruzd's avatar Dmitry Gruzd

Merge branch 'handle-search-query-timeouts' into 'master'

Handle query timeouts better

See merge request gitlab-org/gitlab!75034
parents fa63f8b9 2671aada
......@@ -5,7 +5,7 @@ class SearchController < ApplicationController
include SearchHelper
include RedisTracking
RESCUE_FROM_TIMEOUT_ACTIONS = [:count, :show].freeze
RESCUE_FROM_TIMEOUT_ACTIONS = [:count, :show, :autocomplete].freeze
track_redis_hll_event :show, name: 'i_search_total'
......@@ -74,11 +74,7 @@ class SearchController < ApplicationController
def autocomplete
term = params[:term]
if params[:project_id].present?
@project = Project.find_by(id: params[:project_id])
@project = nil unless can?(current_user, :read_project, @project)
end
@project = search_service.project
@ref = params[:project_ref] if params[:project_ref].present?
render json: search_autocomplete_opts(term).to_json
......@@ -189,17 +185,16 @@ class SearchController < ApplicationController
@timeout = true
if count_action_name?
case action_name.to_sym
when :count
render json: {}, status: :request_timeout
when :autocomplete
render json: [], status: :request_timeout
else
render status: :request_timeout
end
end
def count_action_name?
action_name.to_sym == :count
end
def strip_surrounding_whitespace_from_search
%i(term search).each { |param| params[param]&.strip! }
end
......
......@@ -8,6 +8,10 @@ module API
feature_category :global_search
rescue_from ActiveRecord::QueryCanceled do |e|
render_api_error!({ error: 'Request timed out' }, 408)
end
helpers do
SCOPE_ENTITY = {
merge_requests: Entities::MergeRequestBasic,
......
......@@ -328,6 +328,7 @@ RSpec.describe SearchController do
describe 'GET #autocomplete' do
it_behaves_like 'when the user cannot read cross project', :autocomplete, { term: 'hello' }
it_behaves_like 'with external authorization service enabled', :autocomplete, { term: 'hello' }
it_behaves_like 'support for active record query timeouts', :autocomplete, { term: 'hello' }, :project, :json
end
describe '#append_info_to_payload' do
......
......@@ -122,6 +122,23 @@ RSpec.describe API::Search do
end
end
context 'when DB timeouts occur from global searches', :aggregate_errors do
%w(
issues
merge_requests
milestones
projects
snippet_titles
users
).each do |scope|
it "returns a 408 error if search with scope: #{scope} times out" do
allow(SearchService).to receive(:new).and_raise ActiveRecord::QueryCanceled
get api(endpoint, user), params: { scope: scope, search: 'awesome' }
expect(response).to have_gitlab_http_status(:request_timeout)
end
end
end
context 'when scope is not supported' do
it 'returns 400 error' do
get api(endpoint, user), params: { scope: 'unsupported', search: 'awesome' }
......
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