Fix performance of dashboard metrics by periodically warming cache

This commit is contained in:
Eugen Rochko 2024-11-10 17:06:43 +01:00
parent e22ec25077
commit a36dc01a81
8 changed files with 82 additions and 5 deletions

View file

@ -95,7 +95,7 @@ export default class Counter extends PureComponent {
<div className='sparkline__graph'> <div className='sparkline__graph'>
{!loading && ( {!loading && (
<Sparklines width={259} height={55} data={data[0].data.map(x => x.value * 1)}> <Sparklines width={259} height={55} data={data[0].data.map(x => x.value * 1)} margin={0}>
<SparklinesCurve /> <SparklinesCurve />
</Sparklines> </Sparklines>
)} )}

View file

@ -1315,12 +1315,18 @@ a.sparkline {
&__key { &__key {
font-weight: 500; font-weight: 500;
padding: 11px 10px; padding: 11px 10px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
} }
&__value { &__value {
text-align: end; text-align: end;
color: $darker-text-color; color: $darker-text-color;
padding: 11px 10px; padding: 11px 10px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
} }
&__indicator { &__indicator {

View file

@ -39,6 +39,10 @@ class Admin::Metrics::Dimension::BaseDimension
send(key) if respond_to?(key) send(key) if respond_to?(key)
end end
def perform_for_cache!
Rails.cache.write(cache_key, perform_query, expires_in: CACHE_TTL)
end
protected protected
def load def load

View file

@ -1,7 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
class Admin::Metrics::Measure::BaseMeasure class Admin::Metrics::Measure::BaseMeasure
CACHE_TTL = 5.minutes.freeze CACHE_TTL = 3.hours.freeze
def self.with_params? def self.with_params?
false false
@ -54,6 +54,10 @@ class Admin::Metrics::Measure::BaseMeasure
send(key) if respond_to?(key) send(key) if respond_to?(key)
end end
def perform_for_cache!
Rails.cache.write(cache_key, perform_queries, expires_in: CACHE_TTL)
end
protected protected
def load def load

View file

@ -1,7 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
class Admin::Metrics::Retention class Admin::Metrics::Retention
CACHE_TTL = 5.minutes.freeze CACHE_TTL = 1.day.freeze
class Cohort < ActiveModelSerializers::Model class Cohort < ActiveModelSerializers::Model
attributes :period, :frequency, :data attributes :period, :frequency, :data
@ -30,6 +30,10 @@ class Admin::Metrics::Retention
load load
end end
def perform_for_cache!
Rails.cache.write(cache_key, perform_query, expires_in: CACHE_TTL)
end
protected protected
def load def load

View file

@ -107,7 +107,7 @@
dimension: 'software_versions', dimension: 'software_versions',
end_at: @time_period.last, end_at: @time_period.last,
label: t('admin.dashboard.software'), label: t('admin.dashboard.software'),
limit: 4, limit: 8,
start_at: @time_period.first start_at: @time_period.first
.dashboard__item .dashboard__item
@ -115,5 +115,5 @@
dimension: 'space_usage', dimension: 'space_usage',
end_at: @time_period.last, end_at: @time_period.last,
label: t('admin.dashboard.space'), label: t('admin.dashboard.space'),
limit: 3, limit: 8,
start_at: @time_period.first start_at: @time_period.first

View file

@ -0,0 +1,55 @@
# frozen_string_literal: true
class Scheduler::Admin::DashboardCacheWarmerScheduler
include Sidekiq::Worker
# The values in this file have to align with the values in app/views/admin/dashboard/index.html.haml
# so that the generated cache keys are the same, otherwise cache warming will have no benefit
MEASURES = %w(
new_users
active_users
interactions
opened_reports
resolved_reports
).freeze
DIMENSIONS = %w(
sources
languages
servers
software_versions
space_usage
).freeze
DIMENSION_LIMIT = 8
TIME_PERIOD_DAYS = 29
RETENTION_TIME_PERIOD_MONTHS = 6
def perform
@start_at = TIME_PERIOD_DAYS.days.ago.to_date
@end_at = Time.now.utc.to_date
@retention_start_at = @end_at - RETENTION_TIME_PERIOD_MONTHS.months
@retention_end_at = @end_at
warm_measures_cache!
warm_dimensions_cache!
warm_retention_cache!
end
private
def warm_measures_cache!
Admin::Metrics::Measure.retrieve(MEASURES, @start_at, @end_at, {}).each(&:perform_for_cache!)
end
def warm_dimensions_cache!
Admin::Metrics::Dimension.retrieve(DIMENSIONS, @start_at, @end_at, DIMENSION_LIMIT, {}).each(&:perform_for_cache!)
end
def warm_retention_cache!
Admin::Metrics::Retention.new(@retention_start_at, @retention_end_at, 'month').perform_for_cache!
end
end

View file

@ -67,3 +67,7 @@
interval: 1 hour interval: 1 hour
class: Scheduler::AutoCloseRegistrationsScheduler class: Scheduler::AutoCloseRegistrationsScheduler
queue: scheduler queue: scheduler
dashboard_cache_warmer_scheduler:
interval: 2 hours
class: Scheduler::Admin::DashboardCacheWarmerScheduler
queue: scheduler