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(...) Apartment::Tenant.switch(...)
end end
def self.run_on_each(&block)
["public"].union(Apartment.tenant_names).each do |schema|
switch(schema, &block)
end
end
private private
def create_schema def create_schema

View File

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

View File

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

View File

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

View File

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

View File

@@ -133,6 +133,27 @@ describe Tenant do
end end
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 describe "validations" do
let(:tenant) { build(:tenant) } let(:tenant) { build(:tenant) }