PERF: stop mucking with user stats every 15 minutes

(pushed to twice daily)
This commit is contained in:
Sam 2014-08-07 14:20:42 +10:00
parent b5045a005f
commit cd22b6158c
7 changed files with 26 additions and 22 deletions

View File

@ -10,6 +10,8 @@ module Jobs
Notification.ensure_consistency! Notification.ensure_consistency!
UserAction.ensure_consistency! UserAction.ensure_consistency!
UserBadge.ensure_consistency! UserBadge.ensure_consistency!
# ensure consistent
UserStat.update_view_counts(13.hours.ago)
end end
end end
end end

View File

@ -12,9 +12,6 @@ module Jobs
# Feature topics in categories # Feature topics in categories
CategoryFeaturedTopic.feature_topics CategoryFeaturedTopic.feature_topics
# Update view counts for users
UserStat.update_view_counts
# Update the scores of posts # Update the scores of posts
ScoreCalculator.new.calculate(1.day.ago) ScoreCalculator.new.calculate(1.day.ago)

View File

@ -39,7 +39,7 @@ class PostTiming < ActiveRecord::Base
args) args)
if rows == 0 if rows == 0
Post.where(['topic_id = :topic_id and post_number = :post_number', args]).update_all 'reads = reads + 1'
exec_sql("INSERT INTO post_timings (topic_id, user_id, post_number, msecs) exec_sql("INSERT INTO post_timings (topic_id, user_id, post_number, msecs)
SELECT :topic_id, :user_id, :post_number, :msecs SELECT :topic_id, :user_id, :post_number, :msecs
WHERE NOT EXISTS(SELECT 1 FROM post_timings WHERE NOT EXISTS(SELECT 1 FROM post_timings
@ -48,6 +48,8 @@ class PostTiming < ActiveRecord::Base
AND post_number = :post_number)", AND post_number = :post_number)",
args) args)
Post.where(['topic_id = :topic_id and post_number = :post_number', args]).update_all 'reads = reads + 1'
UserStat.where(user_id: args[:user_id]).update_all 'posts_read_count = posts_read_count + 1'
end end
end end

View File

@ -42,6 +42,7 @@ class TopicViewItem < ActiveRecord::Base
if result.cmd_tuples > 0 if result.cmd_tuples > 0
Topic.where(id: topic_id).update_all 'views = views + 1' Topic.where(id: topic_id).update_all 'views = views + 1'
UserStat.where(user_id: user_id).update_all 'topics_entered = topics_entered + 1' if user_id
end end
# Update the views count in the parent, if it exists. # Update the views count in the parent, if it exists.

View File

@ -4,7 +4,7 @@ class UserStat < ActiveRecord::Base
after_save :trigger_badges after_save :trigger_badges
# Updates the denormalized view counts for all users # Updates the denormalized view counts for all users
def self.update_view_counts def self.update_view_counts(last_seen = 1.hour.ago)
# NOTE: we only update the counts for users we have seen in the last hour # NOTE: we only update the counts for users we have seen in the last hour
# this avoids a very expensive query that may run on the entire user base # this avoids a very expensive query that may run on the entire user base
@ -22,7 +22,7 @@ class UserStat < ActiveRecord::Base
WHERE WHERE
X.user_id = user_stats.user_id AND X.user_id = user_stats.user_id AND
X.c <> topics_entered X.c <> topics_entered
", seen_at: 1.hour.ago ", seen_at: last_seen
# Update denormalzied posts_read_count # Update denormalzied posts_read_count
exec_sql "UPDATE user_stats SET posts_read_count = X.c exec_sql "UPDATE user_stats SET posts_read_count = X.c
@ -35,7 +35,7 @@ class UserStat < ActiveRecord::Base
GROUP BY pt.user_id) AS X GROUP BY pt.user_id) AS X
WHERE X.user_id = user_stats.user_id AND WHERE X.user_id = user_stats.user_id AND
X.c <> posts_read_count X.c <> posts_read_count
", seen_at: 1.hour.ago ", seen_at: last_seen
end end
def update_topic_reply_count def update_topic_reply_count

View File

@ -93,12 +93,6 @@ describe PostTiming do
@timing_attrs = {msecs: 1234, topic_id: @post.topic_id, user_id: @coding_horror.id, post_number: @post.post_number} @timing_attrs = {msecs: 1234, topic_id: @post.topic_id, user_id: @coding_horror.id, post_number: @post.post_number}
end end
it 'creates a post timing record' do
lambda {
PostTiming.record_timing(@timing_attrs)
}.should change(PostTiming, :count).by(1)
end
it 'adds a view to the post' do it 'adds a view to the post' do
lambda { lambda {
PostTiming.record_timing(@timing_attrs) PostTiming.record_timing(@timing_attrs)
@ -107,19 +101,17 @@ describe PostTiming do
end end
describe 'multiple calls' do describe 'multiple calls' do
before do it 'correctly works' do
PostTiming.record_timing(@timing_attrs) PostTiming.record_timing(@timing_attrs)
PostTiming.record_timing(@timing_attrs) PostTiming.record_timing(@timing_attrs)
@timing = PostTiming.find_by(topic_id: @post.topic_id, user_id: @coding_horror.id, post_number: @post.post_number) timing = PostTiming.find_by(topic_id: @post.topic_id, user_id: @coding_horror.id, post_number: @post.post_number)
timing.should be_present
timing.msecs.should == 2468
@coding_horror.user_stat.posts_read_count.should == 1
end end
it 'creates a timing record' do
@timing.should be_present
end
it 'sums the msecs together' do
@timing.msecs.should == 2468
end
end end
describe 'avg times' do describe 'avg times' do

View File

@ -17,4 +17,14 @@ describe TopicViewItem do
TopicViewItem.count.should == 3 TopicViewItem.count.should == 3
end end
it "increases a users view count" do
user = Fabricate(:user)
add(1, "1.1.1.1", user.id)
add(1, "1.1.1.1", user.id)
user.user_stat.reload
user.user_stat.topics_entered.should == 1
end
end end