mirror of
https://github.com/discourse/discourse.git
synced 2024-11-27 11:20:57 -06:00
Cache dashboard data in the controller, not the report model
This commit is contained in:
parent
1e4dd3ea0c
commit
c3c25b894a
@ -5,6 +5,7 @@ Discourse.AdminDashboard.reopenClass({
|
|||||||
var model = Discourse.AdminDashboard.create();
|
var model = Discourse.AdminDashboard.create();
|
||||||
return $.ajax("/admin/dashboard", {
|
return $.ajax("/admin/dashboard", {
|
||||||
type: 'GET',
|
type: 'GET',
|
||||||
|
dataType: 'json',
|
||||||
success: function(json) {
|
success: function(json) {
|
||||||
model.mergeAttributes(json);
|
model.mergeAttributes(json);
|
||||||
model.set('loaded', true);
|
model.set('loaded', true);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
class Admin::DashboardController < Admin::AdminController
|
class Admin::DashboardController < Admin::AdminController
|
||||||
|
|
||||||
|
caches_action :index, expires_in: 1.hour
|
||||||
|
|
||||||
def index
|
def index
|
||||||
render_json_dump(AdminDashboardData.fetch)
|
render_json_dump(AdminDashboardData.fetch)
|
||||||
end
|
end
|
||||||
|
@ -35,98 +35,60 @@ class Report
|
|||||||
|
|
||||||
def self.report_visits(report)
|
def self.report_visits(report)
|
||||||
report.data = []
|
report.data = []
|
||||||
fetch report do
|
UserVisit.by_day(30.days.ago).each do |date, count|
|
||||||
UserVisit.by_day(30.days.ago).each do |date, count|
|
report.data << {x: date, y: count}
|
||||||
report.data << {x: date, y: count}
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.report_signups(report)
|
def self.report_signups(report)
|
||||||
report.data = []
|
report.data = []
|
||||||
fetch report do
|
User.count_by_signup_date(30.days.ago).each do |date, count|
|
||||||
User.count_by_signup_date(30.days.ago).each do |date, count|
|
report.data << {x: date, y: count}
|
||||||
report.data << {x: date, y: count}
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.report_topics(report)
|
def self.report_topics(report)
|
||||||
report.data = []
|
report.data = []
|
||||||
fetch report do
|
Topic.count_per_day(30.days.ago).each do |date, count|
|
||||||
Topic.count_per_day(30.days.ago).each do |date, count|
|
report.data << {x: date, y: count}
|
||||||
report.data << {x: date, y: count}
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.report_posts(report)
|
def self.report_posts(report)
|
||||||
report.data = []
|
report.data = []
|
||||||
fetch report do
|
Post.count_per_day(30.days.ago).each do |date, count|
|
||||||
Post.count_per_day(30.days.ago).each do |date, count|
|
report.data << {x: date, y: count}
|
||||||
report.data << {x: date, y: count}
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.report_flags(report)
|
def self.report_flags(report)
|
||||||
report.data = []
|
report.data = []
|
||||||
fetch report do
|
(0..30).to_a.reverse.each do |i|
|
||||||
(0..30).to_a.reverse.each do |i|
|
if (count = PostAction.where('date(created_at) = ?', i.days.ago.to_date).where(post_action_type_id: PostActionType.flag_types.values).count) > 0
|
||||||
if (count = PostAction.where('date(created_at) = ?', i.days.ago.to_date).where(post_action_type_id: PostActionType.flag_types.values).count) > 0
|
report.data << {x: i.days.ago.to_date.to_s, y: count}
|
||||||
report.data << {x: i.days.ago.to_date.to_s, y: count}
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.report_users_by_trust_level(report)
|
def self.report_users_by_trust_level(report)
|
||||||
report.data = []
|
report.data = []
|
||||||
fetch report do
|
User.counts_by_trust_level.each do |level, count|
|
||||||
User.counts_by_trust_level.each do |level, count|
|
report.data << {x: level.to_i, y: count}
|
||||||
report.data << {x: level.to_i, y: count}
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.report_likes(report)
|
def self.report_likes(report)
|
||||||
report.data = []
|
report.data = []
|
||||||
fetch report do
|
PostAction.count_likes_per_day(30.days.ago).each do |date, count|
|
||||||
PostAction.count_likes_per_day(30.days.ago).each do |date, count|
|
report.data << {x: date, y: count}
|
||||||
report.data << {x: date, y: count}
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.report_emails(report)
|
def self.report_emails(report)
|
||||||
report.data = []
|
report.data = []
|
||||||
fetch report do
|
EmailLog.count_per_day(30.days.ago).each do |date, count|
|
||||||
EmailLog.count_per_day(30.days.ago).each do |date, count|
|
report.data << {x: date, y: count}
|
||||||
report.data << {x: date, y: count}
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def self.fetch(report)
|
|
||||||
unless report.cache and $redis
|
|
||||||
yield
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
data_set = "#{report.type}:data"
|
|
||||||
if $redis.exists(data_set)
|
|
||||||
$redis.get(data_set).split('|').each do |pair|
|
|
||||||
date, count = pair.split(',')
|
|
||||||
report.data << {x: date, y: count.to_i}
|
|
||||||
end
|
|
||||||
else
|
|
||||||
yield
|
|
||||||
$redis.setex data_set, cache_expiry, report.data.map { |item| "#{item[:x]},#{item[:y]}" }.join('|')
|
|
||||||
end
|
|
||||||
rescue Redis::BaseConnectionError
|
|
||||||
yield
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -1,162 +1,88 @@
|
|||||||
# require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
# describe Report do
|
describe Report do
|
||||||
|
|
||||||
|
# describe 'visits report' do
|
||||||
|
# let(:report) { Report.find('visits', cache: false) }
|
||||||
|
|
||||||
# describe 'visits report' do
|
# context "no visits" do
|
||||||
# let(:report) { Report.find('visits', cache: false) }
|
# it "returns an empty report" do
|
||||||
|
# report.data.should be_blank
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
|
||||||
# context "no visits" do
|
# context "with visits" do
|
||||||
# it "returns an empty report" do
|
# let(:user) { Fabricate(:user) }
|
||||||
# report.data.should be_blank
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
|
|
||||||
# context "with visits" do
|
# before do
|
||||||
# let(:user) { Fabricate(:user) }
|
# user.user_visits.create(visited_at: 1.day.ago)
|
||||||
|
# user.user_visits.create(visited_at: 2.days.ago)
|
||||||
|
# end
|
||||||
|
|
||||||
# before do
|
# it "returns a report with data" do
|
||||||
# user.user_visits.create(visited_at: 1.day.ago)
|
# report.data.should be_present
|
||||||
# user.user_visits.create(visited_at: 2.days.ago)
|
# end
|
||||||
# end
|
# end
|
||||||
|
# end
|
||||||
|
|
||||||
# it "returns a report with data" do
|
# [:signup, :topic, :post, :flag, :like, :email].each do |arg|
|
||||||
# report.data.should be_present
|
# describe "#{arg} report" do
|
||||||
# end
|
# pluralized = arg.to_s.pluralize
|
||||||
# end
|
|
||||||
# end
|
|
||||||
|
|
||||||
# [:signup, :topic, :post, :flag, :like, :email].each do |arg|
|
# let(:report) { Report.find(pluralized, cache: false) }
|
||||||
# describe "#{arg} report" do
|
|
||||||
# pluralized = arg.to_s.pluralize
|
|
||||||
|
|
||||||
# let(:report) { Report.find(pluralized, cache: false) }
|
# context "no #{pluralized}" do
|
||||||
|
# it 'returns an empty report' do
|
||||||
|
# report.data.should be_blank
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
|
||||||
# context "no #{pluralized}" do
|
# context "with #{pluralized}" do
|
||||||
# it 'returns an empty report' do
|
# before do
|
||||||
# report.data.should be_blank
|
# fabricator = case arg
|
||||||
# end
|
# when :signup
|
||||||
# end
|
# :user
|
||||||
|
# when :email
|
||||||
|
# :email_log
|
||||||
|
# else
|
||||||
|
# arg
|
||||||
|
# end
|
||||||
|
# Fabricate(fabricator, created_at: 25.hours.ago)
|
||||||
|
# Fabricate(fabricator, created_at: 1.hours.ago)
|
||||||
|
# Fabricate(fabricator, created_at: 1.hours.ago)
|
||||||
|
# end
|
||||||
|
|
||||||
# context "with #{pluralized}" do
|
# it 'returns correct data' do
|
||||||
# before do
|
# report.data[0][:y].should == 1
|
||||||
# fabricator = case arg
|
# report.data[1][:y].should == 2
|
||||||
# when :signup
|
# end
|
||||||
# :user
|
# end
|
||||||
# when :email
|
# end
|
||||||
# :email_log
|
# end
|
||||||
# else
|
|
||||||
# arg
|
|
||||||
# end
|
|
||||||
# Fabricate(fabricator, created_at: 25.hours.ago)
|
|
||||||
# Fabricate(fabricator, created_at: 1.hours.ago)
|
|
||||||
# Fabricate(fabricator, created_at: 1.hours.ago)
|
|
||||||
# end
|
|
||||||
|
|
||||||
# it 'returns correct data' do
|
describe 'users by trust level report' do
|
||||||
# report.data[0][:y].should == 1
|
let(:report) { Report.find('users_by_trust_level', cache: false) }
|
||||||
# report.data[1][:y].should == 2
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
|
|
||||||
# describe 'users by trust level report' do
|
context "no users" do
|
||||||
# let(:report) { Report.find('users_by_trust_level', cache: false) }
|
it "returns an empty report" do
|
||||||
|
report.data.should be_blank
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# context "no users" do
|
context "with users at different trust levels" do
|
||||||
# it "returns an empty report" do
|
before do
|
||||||
# report.data.should be_blank
|
3.times { Fabricate(:user, trust_level: TrustLevel.levels[:visitor]) }
|
||||||
# end
|
2.times { Fabricate(:user, trust_level: TrustLevel.levels[:regular]) }
|
||||||
# end
|
Fabricate(:user, trust_level: TrustLevel.levels[:elder])
|
||||||
|
end
|
||||||
|
|
||||||
# context "with users at different trust levels" do
|
it "returns a report with data" do
|
||||||
# before do
|
report.data.should be_present
|
||||||
# 3.times { Fabricate(:user, trust_level: TrustLevel.levels[:new]) }
|
report.data.find {|d| d[:x] == TrustLevel.levels[:visitor]} [:y].should == 3
|
||||||
# 2.times { Fabricate(:user, trust_level: TrustLevel.levels[:regular]) }
|
report.data.find {|d| d[:x] == TrustLevel.levels[:regular]}[:y].should == 2
|
||||||
# Fabricate(:user, trust_level: TrustLevel.levels[:moderator])
|
report.data.find {|d| d[:x] == TrustLevel.levels[:elder]}[:y].should == 1
|
||||||
# end
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# it "returns a report with data" do
|
end
|
||||||
# report.data.should be_present
|
|
||||||
# report.data.find {|d| d[:x] == TrustLevel.levels[:new]} [:y].should == 3
|
|
||||||
# report.data.find {|d| d[:x] == TrustLevel.levels[:regular]}[:y].should == 2
|
|
||||||
# report.data.find {|d| d[:x] == TrustLevel.levels[:moderator]}[:y].should == 1
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
|
|
||||||
# describe '#fetch' do
|
|
||||||
# context 'signups' do
|
|
||||||
# let(:report) { Report.find('signups', cache: true) }
|
|
||||||
|
|
||||||
# context 'no data' do
|
|
||||||
# context 'cache miss' do
|
|
||||||
# before do
|
|
||||||
# $redis.expects(:exists).with('signups:data').returns(false)
|
|
||||||
# end
|
|
||||||
|
|
||||||
# it 'should cache an empty data set' do
|
|
||||||
# $redis.expects(:setex).with('signups:data', Report.cache_expiry, "")
|
|
||||||
# report.data.should be_blank
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
|
|
||||||
# context 'cache hit' do
|
|
||||||
# before do
|
|
||||||
# $redis.expects(:exists).with('signups:data').returns(true)
|
|
||||||
# end
|
|
||||||
|
|
||||||
# it 'returns the cached empty report' do
|
|
||||||
# User.expects(:count_by_signup_date).never
|
|
||||||
# $redis.expects(:setex).never
|
|
||||||
# $redis.expects(:get).with('signups:data').returns('')
|
|
||||||
# report.data.should be_blank
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
|
|
||||||
# context 'with data' do
|
|
||||||
# before do
|
|
||||||
# Fabricate(:user, created_at: 25.hours.ago)
|
|
||||||
# Fabricate(:user, created_at: 1.hour.ago)
|
|
||||||
# Fabricate(:user, created_at: 1.hour.ago)
|
|
||||||
# end
|
|
||||||
|
|
||||||
# context 'cache miss' do
|
|
||||||
# before do
|
|
||||||
# $redis.expects(:exists).with('signups:data').returns(false)
|
|
||||||
# end
|
|
||||||
|
|
||||||
# it 'should cache the data set' do
|
|
||||||
# $redis.expects(:setex).with do |key, expiry, string|
|
|
||||||
# string =~ /(\d)+-(\d)+-(\d)+,1/ and string =~ /(\d)+-(\d)+-(\d)+,2/
|
|
||||||
# end
|
|
||||||
# report()
|
|
||||||
# end
|
|
||||||
|
|
||||||
# it 'should return correct data' do
|
|
||||||
# report.data[0][:y].should == 1
|
|
||||||
# report.data[1][:y].should == 2
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
|
|
||||||
# context 'cache hit' do
|
|
||||||
# before do
|
|
||||||
# $redis.expects(:exists).with('signups:data').returns(true)
|
|
||||||
# end
|
|
||||||
|
|
||||||
# it 'returns the cached data' do
|
|
||||||
# User.expects(:count_by_signup_date).never
|
|
||||||
# $redis.expects(:setex).never
|
|
||||||
# $redis.expects(:get).with('signups:data').returns("#{2.days.ago.to_date.to_s},1|#{1.day.ago.to_date.to_s},2")
|
|
||||||
# report.data[0][:y].should == 1
|
|
||||||
# report.data[1][:y].should == 2
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
|
|
||||||
|
|
||||||
# end
|
|
Loading…
Reference in New Issue
Block a user