From 181ab8948558aebd9b38c1db474a88ba74b3d3c0 Mon Sep 17 00:00:00 2001 From: Sam Date: Mon, 28 Sep 2015 16:43:38 +1000 Subject: [PATCH] PERF: introduce fragment caches in site serializer --- app/models/category.rb | 6 +++++- app/models/group.rb | 7 +++++++ app/models/post_action_type.rb | 10 ++++++++++ app/models/site.rb | 19 +++++-------------- app/models/topic.rb | 6 +++++- app/serializers/site_serializer.rb | 26 +++++++++++++++++++++++--- 6 files changed, 55 insertions(+), 19 deletions(-) diff --git a/app/models/category.rb b/app/models/category.rb index c8fb148c663..89e9fd77430 100644 --- a/app/models/category.rb +++ b/app/models/category.rb @@ -193,7 +193,11 @@ SQL end def topic_url - topic_only_relative_url.try(:relative_url) + if has_attribute?("topic_slug") + Topic.relative_url(topic_id, topic_slug) + else + topic_only_relative_url.try(:relative_url) + end end def description_text diff --git a/app/models/group.rb b/app/models/group.rb index 27959ac7280..c14f5bb758b 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -15,6 +15,13 @@ class Group < ActiveRecord::Base after_save :update_primary_group after_save :update_title + after_save :expire_cache + after_destroy :expire_cache + + def expire_cache + ApplicationSerializer.expire_cache_fragment!("group_names") + end + validate :name_format_validator validates_uniqueness_of :name, case_sensitive: false diff --git a/app/models/post_action_type.rb b/app/models/post_action_type.rb index 847c03a64e5..2f4829c347c 100644 --- a/app/models/post_action_type.rb +++ b/app/models/post_action_type.rb @@ -1,7 +1,17 @@ require_dependency 'enum' +require_dependency 'distributed_cache' class PostActionType < ActiveRecord::Base + after_save :expire_cache + after_destroy :expire_cache + + def expire_cache + ApplicationSerializer.expire_cache_fragment!("post_action_types") + ApplicationSerializer.expire_cache_fragment!("post_action_flag_types") + end + class << self + def ordered order('position asc') end diff --git a/app/models/site.rb b/app/models/site.rb index 5f3cf7981df..264c7cb8103 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -13,14 +13,6 @@ class Site SiteSetting end - def post_action_types - PostActionType.ordered - end - - def topic_flag_types - post_action_types.where(name_key: ['inappropriate', 'spam', 'notify_moderators']) - end - def notification_types Notification.types end @@ -29,10 +21,6 @@ class Site TrustLevel.all end - def groups - @groups ||= Group.order(:name).map { |g| { id: g.id, name: g.name } } - end - def user_fields UserField.all end @@ -41,7 +29,8 @@ class Site @categories ||= begin categories = Category .secured(@guardian) - .includes(:topic_only_relative_url) + .joins('JOIN topics t on t.id = categories.topic_id') + .select('categories.*, t.slug topic_slug') .order(:position) categories = categories.to_a @@ -53,7 +42,9 @@ class Site end end - allowed_topic_create = Set.new(Category.topic_create_allowed(@guardian).pluck(:id)) + allowed_topic_create_ids = + @guardian.anonymous? ? [] : Category.topic_create_allowed(@guardian).pluck(:id) + allowed_topic_create = Set.new(allowed_topic_create_ids) by_id = {} diff --git a/app/models/topic.rb b/app/models/topic.rb index 6f7f9b515aa..47d7f415864 100644 --- a/app/models/topic.rb +++ b/app/models/topic.rb @@ -736,12 +736,16 @@ class Topic < ActiveRecord::Base self.class.url id, slug, post_number end - def relative_url(post_number=nil) + def self.relative_url(id, slug, post_number=nil) url = "#{Discourse.base_uri}/t/#{slug}/#{id}" url << "/#{post_number}" if post_number.to_i > 1 url end + def relative_url(post_number=nil) + Topic.relative_url(id, slug, post_number) + end + def unsubscribe_url "#{url}/unsubscribe" end diff --git a/app/serializers/site_serializer.rb b/app/serializers/site_serializer.rb index dec52ed2f2d..174008ce084 100644 --- a/app/serializers/site_serializer.rb +++ b/app/serializers/site_serializer.rb @@ -12,15 +12,35 @@ class SiteSerializer < ApplicationSerializer :is_readonly, :disabled_plugins, :user_field_max_length, - :suppressed_from_homepage_category_ids + :suppressed_from_homepage_category_ids, + :post_action_types, + :topic_flag_types has_many :categories, serializer: BasicCategorySerializer, embed: :objects - has_many :post_action_types, embed: :objects - has_many :topic_flag_types, serializer: TopicFlagTypeSerializer, embed: :objects has_many :trust_levels, embed: :objects has_many :archetypes, embed: :objects, serializer: ArchetypeSerializer has_many :user_fields, embed: :objects, serialzer: UserFieldSerializer + def groups + cache_fragment("group_names") do + Group.order(:name).pluck(:id,:name).map { |id,name| { id: id, name: name } }.as_json + end + end + + def post_action_types + cache_fragment("post_action_types") do + ActiveModel::ArraySerializer.new(PostActionType.ordered).as_json + end + end + + def topic_flag_types + cache_fragment("post_action_flag_types") do + flags = PostActionType.ordered.where(name_key: ['inappropriate', 'spam', 'notify_moderators']) + ActiveModel::ArraySerializer.new(flags, each_serializer: TopicFlagTypeSerializer).as_json + end + + end + def default_archetype Archetype.default end