mirror of
https://github.com/discourse/discourse.git
synced 2025-05-30 23:48:44 +08:00
PERF: rate limit search, and add anon cache for search results (#9969)
Adds new hidden site settings for rate limits: 30 for logged in users, 15 for anon Adds an anon cache for searching, caches results of searches for 1 minute
This commit is contained in:
@ -28,6 +28,10 @@ class SearchController < ApplicationController
|
||||
raise Discourse::InvalidParameters.new("string contains null byte")
|
||||
end
|
||||
|
||||
rate_limit_errors = rate_limit_search
|
||||
|
||||
discourse_expires_in 1.minute
|
||||
|
||||
search_args = {
|
||||
type_filter: 'topic',
|
||||
guardian: guardian,
|
||||
@ -48,7 +52,10 @@ class SearchController < ApplicationController
|
||||
search_args[:ip_address] = request.remote_ip
|
||||
search_args[:user_id] = current_user.id if current_user.present?
|
||||
|
||||
if site_overloaded?
|
||||
if rate_limit_errors
|
||||
result = Search::GroupedSearchResults.new(search_args[:type_filter], @search_term, context, false, 0)
|
||||
result.error = I18n.t("rate_limiter.slow_down")
|
||||
elsif site_overloaded?
|
||||
result = Search::GroupedSearchResults.new(search_args[:type_filter], @search_term, context, false, 0)
|
||||
result.error = I18n.t("search.extreme_load_error")
|
||||
else
|
||||
@ -76,6 +83,10 @@ class SearchController < ApplicationController
|
||||
raise Discourse::InvalidParameters.new("string contains null byte")
|
||||
end
|
||||
|
||||
rate_limit_errors = rate_limit_search
|
||||
|
||||
discourse_expires_in 1.minute
|
||||
|
||||
search_args = { guardian: guardian }
|
||||
|
||||
search_args[:type_filter] = params[:type_filter] if params[:type_filter].present?
|
||||
@ -94,7 +105,10 @@ class SearchController < ApplicationController
|
||||
search_args[:user_id] = current_user.id if current_user.present?
|
||||
search_args[:restrict_to_archetype] = params[:restrict_to_archetype] if params[:restrict_to_archetype].present?
|
||||
|
||||
if site_overloaded?
|
||||
if rate_limit_errors
|
||||
result = Search::GroupedSearchResults.new(search_args[:type_filter], @search_term, context, false, 0)
|
||||
result.error = I18n.t("rate_limiter.slow_down")
|
||||
elsif site_overloaded?
|
||||
result = GroupedSearchResults.new(search_args["type_filter"], params[:term], context, false, 0)
|
||||
else
|
||||
search = Search.new(params[:term], search_args)
|
||||
@ -140,6 +154,19 @@ class SearchController < ApplicationController
|
||||
(queue_time > GlobalSetting.disable_search_queue_threshold)
|
||||
end
|
||||
|
||||
def rate_limit_search
|
||||
begin
|
||||
if current_user.present?
|
||||
RateLimiter.new(current_user, "search-min", SiteSetting.rate_limit_search_user, 1.minute).performed!
|
||||
else
|
||||
RateLimiter.new(nil, "search-min-#{request.remote_ip}", SiteSetting.rate_limit_search_anon, 1.minute).performed!
|
||||
end
|
||||
rescue RateLimiter::LimitExceeded => e
|
||||
return e
|
||||
end
|
||||
false
|
||||
end
|
||||
|
||||
def cancel_overloaded_search
|
||||
if site_overloaded?
|
||||
render_json_error I18n.t("search.extreme_load_error"), status: 409
|
||||
|
Reference in New Issue
Block a user