Run DB rake tasks on all tenants

Some tasks don't have to run on every tenant. The task to calculate the
TSV is only done for records which were present before we added the TSV
column, and that isn't going to happen in any tenants because we added
the TSV column before adding the tenants table. Similarly, the migration
needed for existing polls isn't necessary because there weren't any
tenants before we allowed to set the starting/ending time to polls.

We aren't adding any tests for these tasks because tests for rake tasks
are slow and tests creating tenants are also slow, making the
combination of the two even slower, particularly if we add tests for
every single task we're changing. We're adding tests for the
`.run_on_each` method instead.
This commit is contained in:
Javi Martín
2022-09-24 19:28:13 +02:00
parent fe9463cb5f
commit 9759288f3b
6 changed files with 54 additions and 17 deletions

View File

@@ -43,6 +43,12 @@ class Tenant < ApplicationRecord
Apartment::Tenant.switch(...)
end
def self.run_on_each(&block)
["public"].union(Apartment.tenant_names).each do |schema|
switch(schema, &block)
end
end
private
def create_schema

View File

@@ -1,8 +1,10 @@
namespace :files do
desc "Removes cached attachments which weren't deleted for some reason"
task remove_old_cached_attachments: :environment do
ActiveStorage::Blob.unattached
.where("active_storage_blobs.created_at <= ?", 1.day.ago)
.find_each(&:purge_later)
Tenant.run_on_each do
ActiveStorage::Blob.unattached
.where("active_storage_blobs.created_at <= ?", 1.day.ago)
.find_each(&:purge_later)
end
end
end

View File

@@ -2,7 +2,7 @@ namespace :settings do
desc "Add new settings"
task add_new_settings: :environment do
ApplicationLogger.new.info "Adding new settings"
Setting.add_new_settings
Tenant.run_on_each { Setting.add_new_settings }
end
desc "Rename existing settings"

View File

@@ -2,23 +2,28 @@ namespace :stats do
desc "Generates stats which are not cached yet"
task generate: :environment do
ApplicationLogger.new.info "Updating budget and poll stats"
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
Tenant.run_on_each do
admin_ability = Ability.new(Administrator.first.user)
Poll.accessible_by(admin_ability, :stats).find_each do |poll|
Poll::Stats.new(poll).generate
print "."
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
[Budget, Poll].each do |model_class|
model_class.find_each { |record| record.find_or_create_stats_version.touch }
Tenant.run_on_each do
[Budget, Poll].each do |model_class|
model_class.find_each { |record| record.find_or_create_stats_version.touch }
end
end
end

View File

@@ -5,9 +5,12 @@ namespace :votes do
models.each do |model|
print "Updating votes hot_score for #{model}s"
model.find_each do |resource|
new_hot_score = resource.calculate_hot_score
resource.update_columns(hot_score: new_hot_score, updated_at: Time.current)
Tenant.run_on_each do
model.find_each do |resource|
new_hot_score = resource.calculate_hot_score
resource.update_columns(hot_score: new_hot_score, updated_at: Time.current)
end
end
puts ""
end

View File

@@ -133,6 +133,27 @@ describe Tenant do
end
end
describe ".run_on_each" do
it "runs the code on all tenants, including the default one" do
create(:tenant, schema: "andromeda")
create(:tenant, schema: "milky-way")
Tenant.run_on_each do
Setting["org_name"] = "oh-my-#{Tenant.current_schema}"
end
expect(Setting["org_name"]).to eq "oh-my-public"
Tenant.switch("andromeda") do
expect(Setting["org_name"]).to eq "oh-my-andromeda"
end
Tenant.switch("milky-way") do
expect(Setting["org_name"]).to eq "oh-my-milky-way"
end
end
end
describe "validations" do
let(:tenant) { build(:tenant) }