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 ...@@ -5,7 +5,7 @@ class SearchController < ApplicationController
include SearchHelper include SearchHelper
include RedisTracking 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' track_redis_hll_event :show, name: 'i_search_total'
...@@ -74,11 +74,7 @@ class SearchController < ApplicationController ...@@ -74,11 +74,7 @@ class SearchController < ApplicationController
def autocomplete def autocomplete
term = params[:term] term = params[:term]
if params[:project_id].present? @project = search_service.project
@project = Project.find_by(id: params[:project_id])
@project = nil unless can?(current_user, :read_project, @project)
end
@ref = params[:project_ref] if params[:project_ref].present? @ref = params[:project_ref] if params[:project_ref].present?
render json: search_autocomplete_opts(term).to_json render json: search_autocomplete_opts(term).to_json
...@@ -189,17 +185,16 @@ class SearchController < ApplicationController ...@@ -189,17 +185,16 @@ class SearchController < ApplicationController
@timeout = true @timeout = true
if count_action_name? case action_name.to_sym
when :count
render json: {}, status: :request_timeout render json: {}, status: :request_timeout
when :autocomplete
render json: [], status: :request_timeout
else else
render status: :request_timeout render status: :request_timeout
end end
end end
def count_action_name?
action_name.to_sym == :count
end
def strip_surrounding_whitespace_from_search def strip_surrounding_whitespace_from_search
%i(term search).each { |param| params[param]&.strip! } %i(term search).each { |param| params[param]&.strip! }
end end
......
...@@ -8,6 +8,10 @@ module API ...@@ -8,6 +8,10 @@ module API
feature_category :global_search feature_category :global_search
rescue_from ActiveRecord::QueryCanceled do |e|
render_api_error!({ error: 'Request timed out' }, 408)
end
helpers do helpers do
SCOPE_ENTITY = { SCOPE_ENTITY = {
merge_requests: Entities::MergeRequestBasic, merge_requests: Entities::MergeRequestBasic,
......
...@@ -328,6 +328,7 @@ RSpec.describe SearchController do ...@@ -328,6 +328,7 @@ RSpec.describe SearchController do
describe 'GET #autocomplete' do describe 'GET #autocomplete' do
it_behaves_like 'when the user cannot read cross project', :autocomplete, { term: 'hello' } 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 'with external authorization service enabled', :autocomplete, { term: 'hello' }
it_behaves_like 'support for active record query timeouts', :autocomplete, { term: 'hello' }, :project, :json
end end
describe '#append_info_to_payload' do describe '#append_info_to_payload' do
......
...@@ -122,6 +122,23 @@ RSpec.describe API::Search do ...@@ -122,6 +122,23 @@ RSpec.describe API::Search do
end end
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 context 'when scope is not supported' do
it 'returns 400 error' do it 'returns 400 error' do
get api(endpoint, user), params: { scope: 'unsupported', search: 'awesome' } 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