0
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-08-08 17:53:55 +08:00
discourse/spec/jobs/scheduled/maintain_user_visit_daily_rollups_spec.rb
Alan Guo Xiang Tan 395077a745
PERF: Use daily rollups for DAU/MAU reports (#41958)
DAU/MAU reports previously calculated every requested date from the full
user visit history, so dashboard requests became slower as that history
grew.

Persist the daily DAU and trailing-30-day MAU values and have the shared
report read only those rollups. The scheduled job builds all existing
history on its first successful run, then refreshes yesterday and today
every three hours. Replacements are atomic, so a failed calculation
leaves the previous report data intact.
2026-07-24 09:52:40 +08:00

50 lines
1.8 KiB
Ruby
Vendored

# frozen_string_literal: true
RSpec.describe Jobs::MaintainUserVisitDailyRollups do
subject(:job) { described_class.new }
fab!(:recent_visitor, :user)
fab!(:historical_visitor, :user)
before { freeze_time(Time.zone.local(2026, 7, 23, 12)) }
describe "#execute" do
it "aggregates the complete visit history on its first run" do
recent_visitor.user_visits.create!(visited_at: Time.zone.today)
historical_visitor.user_visits.create!(visited_at: 10.days.ago)
job.execute({})
expect(UserVisitDailyRollup.order(:date).pluck(:date, :dau, :mau)).to eq(
[[10.days.ago.to_date, 1, 1], [Time.zone.today, 1, 2]],
)
end
it "refreshes only yesterday and today after the initial aggregation" do
recent_visitor.user_visits.create!(visited_at: Time.zone.today)
historical_visitor.user_visits.create!(visited_at: 10.days.ago)
job.execute({})
late_historical_visitor = Fabricate(:user)
late_historical_visitor.user_visits.create!(visited_at: 40.days.ago)
another_recent_visitor = Fabricate(:user)
another_recent_visitor.user_visits.create!(visited_at: Time.zone.today)
job.execute({})
expect(UserVisitDailyRollup.where(date: 40.days.ago).exists?).to eq(false)
expect(UserVisitDailyRollup.find_by(date: Time.zone.today)).to have_attributes(dau: 2, mau: 3)
end
it "fills active dates since the most recent rollup" do
Fabricate(:user_visit_daily_rollup, date: 3.days.ago)
historical_visitor.user_visits.create!(visited_at: 2.days.ago)
recent_visitor.user_visits.create!(visited_at: Time.zone.today)
job.execute({})
expect(UserVisitDailyRollup.order(:date).pluck(:date)).to eq(
[3.days.ago.to_date, 2.days.ago.to_date, Time.zone.today],
)
end
end
end