From a5646fcdb3416dd7f343169f011705e097316270 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mart=C3=ADn?= Date: Thu, 18 Apr 2024 21:11:54 +0200 Subject: [PATCH] Remove Cron job to generate stats Since now generating stats (assuming the results aren't in the cache) only takes a few seconds even when there are a hundred thousand participants, as opposed to the several minutes it took to generate them when we introduced the Cron job, we can simply generate the stats during the first request to the stats page. Note that, in order to avoid creating a temporary table when the stats are cached, we're making sure we only create this table when we need to. Otherwise, we could spend up to 1 second on every request to the stats page creating a table that isn't going to be used. Also note we're using an instance variable to check whether we're creating a table; I tried to use `table_exists?`, but it didn't work. I wonder whether `table_exists?` doesn't detect temporary tables. --- app/controllers/budgets/stats_controller.rb | 2 +- app/controllers/polls_controller.rb | 2 +- app/models/concerns/statisticable.rb | 9 +++++++-- config/schedule.rb | 4 ---- lib/tasks/stats.rake | 22 --------------------- 5 files changed, 9 insertions(+), 30 deletions(-) diff --git a/app/controllers/budgets/stats_controller.rb b/app/controllers/budgets/stats_controller.rb index 33480238d..353ff113b 100644 --- a/app/controllers/budgets/stats_controller.rb +++ b/app/controllers/budgets/stats_controller.rb @@ -8,7 +8,7 @@ module Budgets def show authorize! :read_stats, @budget - @stats = Budget::Stats.new(@budget) + @stats = Budget::Stats.new(@budget).tap(&:generate) @headings = @budget.headings.sort_by_name end diff --git a/app/controllers/polls_controller.rb b/app/controllers/polls_controller.rb index ecb8ffadb..80b72309b 100644 --- a/app/controllers/polls_controller.rb +++ b/app/controllers/polls_controller.rb @@ -23,7 +23,7 @@ class PollsController < ApplicationController end def stats - @stats = Poll::Stats.new(@poll) + @stats = Poll::Stats.new(@poll).tap(&:generate) end def results diff --git a/app/models/concerns/statisticable.rb b/app/models/concerns/statisticable.rb index 8e4ea424c..d644f0dec 100644 --- a/app/models/concerns/statisticable.rb +++ b/app/models/concerns/statisticable.rb @@ -48,10 +48,9 @@ module Statisticable def generate User.transaction do - create_participants_table - begin define_singleton_method :participants do + create_participants_table unless participants_table_created? participants_class.all end @@ -176,10 +175,12 @@ module Statisticable ) User.connection.add_index participants_table_name, :date_of_birth User.connection.add_index participants_table_name, :geozone_id + @participants_table_created = true end def drop_participants_table User.connection.drop_table(participants_table_name, if_exists: true, temporary: true) + @participants_table_created = false end def participants_table_name @@ -190,6 +191,10 @@ module Statisticable @participants_class ||= Class.new(User).tap { |klass| klass.table_name = participants_table_name } end + def participants_table_created? + @participants_table_created.present? + end + def total_participants_with_gender @total_participants_with_gender ||= participants.where.not(gender: nil).distinct.count end diff --git a/config/schedule.rb b/config/schedule.rb index b0755dbaf..fcfd626e3 100644 --- a/config/schedule.rb +++ b/config/schedule.rb @@ -27,10 +27,6 @@ every 1.day, at: "5:00 am" do rake "-s sitemap:refresh:no_ping" end -every 2.hours do - rake "-s stats:generate" -end - every 1.day, at: "1:00 am", roles: [:cron] do rake "files:remove_old_cached_attachments" end diff --git a/lib/tasks/stats.rake b/lib/tasks/stats.rake index b7d397301..526309823 100644 --- a/lib/tasks/stats.rake +++ b/lib/tasks/stats.rake @@ -1,23 +1,4 @@ namespace :stats do - desc "Generates stats which are not cached yet" - task generate: :environment do - ApplicationLogger.new.info "Updating budget and poll stats" - - Tenant.run_on_each do - admin_ability = Ability.new(Administrator.first.user) - - Budget.accessible_by(admin_ability, :read_stats).find_each do |budget| - Budget::Stats.new(budget).generate - print "." - end - - Poll.accessible_by(admin_ability, :stats).find_each do |poll| - Poll::Stats.new(poll).generate - print "." - end - end - end - desc "Expires stats cache" task expire_cache: :environment do Tenant.run_on_each do @@ -26,7 +7,4 @@ namespace :stats do end end end - - desc "Deletes stats cache and generates it again" - task regenerate: [:expire_cache, :generate] end