diff --git a/app/controllers/autocomplete_controller.rb b/app/controllers/autocomplete_controller.rb index 68c46d793..0b36168db 100644 --- a/app/controllers/autocomplete_controller.rb +++ b/app/controllers/autocomplete_controller.rb @@ -8,6 +8,10 @@ class AutocompleteController < ApplicationController @autocomplete = AutocompleteService.new(@query, @type, current_user: CurrentUser.user, limit: @limit) @results = @autocomplete.autocomplete_results + @expires_in = @autocomplete.cache_duration + @public = @autocomplete.cache_publicly? + + expires_in @expires_in, public: @public unless response.cache_control.present? respond_with(@results) end end diff --git a/app/logical/autocomplete_service.rb b/app/logical/autocomplete_service.rb index d05cb6696..8ae91392d 100644 --- a/app/logical/autocomplete_service.rb +++ b/app/logical/autocomplete_service.rb @@ -1,4 +1,6 @@ class AutocompleteService + extend Memoist + POST_STATUSES = %w[active deleted pending flagged appealed banned modqueue unmoderated] STATIC_METATAGS = { @@ -197,4 +199,29 @@ class AutocompleteService results = autocomplete_tag(string).map { |result| result[:value] } [query, results] end + + def cache_duration + if autocomplete_results.size == limit + 24.hours + else + 1.hour + end + end + + # Queries that don't depend on the current user are safe to cache publicly. + def cache_publicly? + if type == :tag_query && parsed_search&.type == :tag + true + elsif type.in?(%i[tag artist wiki_page pool opensearch]) + true + else + false + end + end + + def parsed_search + PostQueryBuilder.new(query).terms.first + end + + memoize :autocomplete_results end