PERF: optimise featuring of topics and users

Previously this would delete all features and recreate, causing
uneeded network traffic and db pain
This commit is contained in:
Sam 2014-01-30 10:32:04 +11:00
parent 29c3767b7f
commit 43ceaae7ba
3 changed files with 31 additions and 12 deletions

View file

@ -5,18 +5,25 @@ class CategoryFeaturedTopic < ActiveRecord::Base
# Populates the category featured topics
def self.feature_topics
transaction do
Category.all.each do |c|
feature_topics_for(c)
CategoryFeaturedUser.feature_users_in(c)
current = {}
CategoryFeaturedTopic.select(:topic_id, :category_id).order(:rank).each do |f|
(current[f.category_id] ||= []) << f.topic_id
end
Category.select(:id, :topic_id).all.each do |c|
feature_topics_for(c, current[c.id] || [])
CategoryFeaturedUser.feature_users_in(c.id)
end
end
end
def self.feature_topics_for(c)
def self.feature_topics_for(c, existing=nil)
return if c.blank?
query = TopicQuery.new(self.fake_admin, per_page: SiteSetting.category_featured_topics, except_topic_ids: [c.topic_id], visible: true)
results = query.list_category(c).topic_ids.to_a
results = query.list_category(c).topic_ids
return if results == existing
CategoryFeaturedTopic.transaction do
CategoryFeaturedTopic.delete_all(category_id: c.id)

View file

@ -6,7 +6,14 @@ class CategoryFeaturedUser < ActiveRecord::Base
5
end
def self.feature_users_in(category)
def self.feature_users_in(category_or_category_id)
category_id =
if Fixnum === category_or_category_id
category_or_category_id
else
category_or_category_id.id
end
# Figure out most recent posters in the category
most_recent_user_ids = exec_sql "
SELECT x.user_id
@ -21,12 +28,17 @@ class CategoryFeaturedUser < ActiveRecord::Base
) AS x
ORDER BY x.created_at DESC
LIMIT :max_featured_users;
", category_id: category.id, max_featured_users: max_featured_users
", category_id: category_id, max_featured_users: max_featured_users
user_ids = most_recent_user_ids.map{|uc| uc['user_id'].to_i}
current = CategoryFeaturedUser.where(category_id: category_id).order(:id).pluck(:user_id)
return if current == user_ids
transaction do
CategoryFeaturedUser.delete_all category_id: category.id
most_recent_user_ids.each do |uc|
create(category_id: category.id, user_id: uc['user_id'])
CategoryFeaturedUser.delete_all category_id: category_id
user_ids.each do |user_id|
create(category_id: category_id, user_id: user_id)
end
end

View file

@ -42,8 +42,8 @@ class TopicList
end
def topic_ids
return [] if @topics_input.blank?
@topics_input.map {|t| t.id}
return [] unless @topics_input
@topics_input.pluck(:id)
end
def attributes